Architecture Patterns
Это содержимое пока не доступно на вашем языке.
Overview
Section titled “Overview”Proven patterns for organising your Wails application.
Service Layer Pattern
Section titled “Service Layer Pattern”Structure
Section titled “Structure”app/├── main.go├── services/│ ├── user_service.go│ ├── data_service.go│ └── file_service.go└── models/ └── user.goImplementation
Section titled “Implementation”// Service interfacetype UserService interface { Create(email, password string) (*User, error) GetByID(id int) (*User, error) Update(user *User) error Delete(id int) error}
// Implementationtype userService struct { app *application.App db *sql.DB}
func NewUserService(app *application.App, db *sql.DB) UserService { return &userService{app: app, db: db}}Repository Pattern
Section titled “Repository Pattern”Structure
Section titled “Structure”// Repository interfacetype UserRepository interface { Create(user *User) error FindByID(id int) (*User, error) Update(user *User) error Delete(id int) error}
// Service uses repositorytype UserService struct { repo UserRepository}
func (s *UserService) Create(email, password string) (*User, error) { user := &User{Email: email} return user, s.repo.Create(user)}Event-Driven Architecture
Section titled “Event-Driven Architecture”Event Bus
Section titled “Event Bus”type EventBus struct { app *application.App listeners map[string][]func(interface{}) mu sync.RWMutex}
func (eb *EventBus) Subscribe(event string, handler func(interface{})) { eb.mu.Lock() defer eb.mu.Unlock() eb.listeners[event] = append(eb.listeners[event], handler)}
func (eb *EventBus) Publish(event string, data interface{}) { eb.mu.RLock() handlers := eb.listeners[event] eb.mu.RUnlock()
for _, handler := range handlers { go handler(data) }}// SubscribeeventBus.Subscribe("user.created", func(data interface{}) { user := data.(*User) sendWelcomeEmail(user)})
// PublisheventBus.Publish("user.created", user)Dependency Injection
Section titled “Dependency Injection”Manual DI
Section titled “Manual DI”type App struct { userService *UserService fileService *FileService db *sql.DB}
func NewApp() *App { db := openDatabase()
return &App{ db: db, userService: NewUserService(db), fileService: NewFileService(db), }}Using Wire
Section titled “Using Wire”//go:build wireinject
func InitializeApp() (*App, error) { wire.Build( openDatabase, NewUserService, NewFileService, NewApp, ) return nil, nil}State Management
Section titled “State Management”Centralised State
Section titled “Centralised State”type AppState struct { currentUser *User settings *Settings mu sync.RWMutex}
func (s *AppState) SetUser(user *User) { s.mu.Lock() defer s.mu.Unlock() s.currentUser = user}
func (s *AppState) GetUser() *User { s.mu.RLock() defer s.mu.RUnlock() return s.currentUser}Best Practices
Section titled “Best Practices”- Separate concerns
- Use interfaces
- Inject dependencies
- Handle errors properly
- Keep services focused
- Document architecture
❌ Don’t
Section titled “❌ Don’t”- Don’t create god objects
- Don’t tightly couple components
- Don’t skip error handling
- Don’t ignore concurrency
- Don’t over-engineer
Next Steps
Section titled “Next Steps”- Security - Security best practices
- Best Practices - Bindings best practices