1. 單例模式(Singleton Pattern)
特點:確保一個類只有一個例項,並提供一個全域性訪問點。
優點:保證資源或狀態的全域性唯一性,減少資源消耗。
缺點:反模組化,測試困難。
應用場景:配置管理器、連線池、日誌記錄器等。
程式碼示例:
type singleton struct { value string } var instance *singleton // 定義一個結構體Singleton,用於儲存單例的例項資料 type singleton struct { value string // 這裏可以儲存單例物件的任何資料 } // 定義一個Once物件,用於確保初始化操作只執行一次 var once sync.Once // 定義一個全域性變數instance,用於儲存單例的例項 var instance *singleton // 初始化函式,由Once.Do呼叫 func initSingleton() { instance = &singleton{value: "unique instance"} // 這裏初始化singleton例項 } // getInstance函式用於獲取單例的例項 func getInstance() *singleton { // 執行initSingleton,確保instance只被初始化一次 once.Do(initSingleton) return instance // 返回單例的例項 } func main() { // 獲取單例例項 singletonInstance := getInstance() fmt.Println(singletonInstance.value) // 再次獲取單例例項,將返回相同的例項 anotherInstance := getInstance() if singletonInstance == anotherInstance { fmt.Println("Both instances are the same") } }
2. 工廠模式(Factory Pattern)
特點:封裝物件建立過程,由子類決定例項化哪個類。
優點:提高模組獨立性,易於擴充套件。
缺點:類數量可能急劇增加,工廠類可能過於龐大。
應用場景:資料庫連線、GUI元件、支付閘道器等。
程式碼示例:
// 定義產品介面,宣告了所有具體產品物件必須實現的操作 type Product interface { operation() } // 定義具體產品實現介面 type ConcreteProductA struct{} func (p *ConcreteProductA) operation() { fmt.Println("Operation of ConcreteProductA") } // 定義抽象工廠介面,宣告了工廠方法 type Creator interface { factoryMethod() Product } // 定義具體工廠實現介面 type CreatorA struct{} func (c *CreatorA) factoryMethod() Product { return &ConcreteProductA{} // 返回具體產品的例項 } func main() { // 使用工廠建立產品 creatorA := &CreatorA{} productA := creatorA.factoryMethod() productA.operation() }
3. 觀察者模式(Observer Pattern)
特點:定義物件間一對多的依賴關係,自動更新依賴物件。
優點:降低耦合度,擴充套件性好。
缺點:可能造成效能問題,系統難以維護。
應用場景:事件監聽系統、UI更新、訊息系統等。
程式碼示例:
// 定義觀察者介面,宣告了更新方法 type Observer interface { Update(string) } // 定義主題,包含觀察者列表和註冊、通知觀察者的方法 type Subject struct { observers []Observer } func (s *Subject) Attach(observer Observer) { s.observers = append(s.observers, observer) } func (s *Subject) Notify(message string) { for _, observer := range s.observers { observer.Update(message) // 通知所有觀察者 } } // 定義具體觀察者實現介面 type ConcreteObserverA struct { name string } func (c *ConcreteObserverA) Update(message string) { fmt.Printf("%s received message: %s\n", c.name, message) } func main() { subject := &Subject{} observerA := &ConcreteObserverA{name: "Observer A"} subject.Attach(observerA) // 註冊觀察者 subject.Notify("State changed to State 1") // 通知觀察者 }
4. 裝飾者模式(Decorator Pattern)
特點:動態地給物件新增額外職責或功能。
優點:增加職責動態且可撤銷,多個裝飾者可組合使用。
缺點:系統複雜,可能影響效能。
應用場景:日誌記錄、快取、安全控制等。
程式碼示例:
// 定義元件介面,宣告了元件的操作 type Component interface { operation() } // 定義具體元件實現介面 type ConcreteComponent struct{} func (c *ConcreteComponent) operation() { fmt.Println("ConcreteComponent: performing basic operation") } // 定義裝飾者抽象類,包含元件介面型別的欄位 type Decorator struct { component Component } // 裝飾者實現元件的操作,委託給元件 func (d *Decorator) operation() { if d.component != nil { d.component.operation() } } // 定義具體裝飾者實現裝飾者抽象類 type ConcreteDecoratorA struct { Decorator } func (cda *ConcreteDecoratorA) operation() { cda.Decorator.operation() // 呼叫裝飾的元件操作 fmt.Println("ConcreteDecoratorA: added additional responsibilities") } func main() { component := &ConcreteComponent{} decoratorA := &ConcreteDecoratorA{Decorator{component}} decoratorA.operation() // 裝飾後的操作 }
5. 策略模式(Strategy Pattern)
特點:定義演算法家族,封裝起來,互相替換。
優點:演算法變化獨立於客戶端,易於新增新演算法。
缺點:客戶端需要了解策略類差異。
應用場景:演算法選擇、支付方式、排序演算法等。
程式碼示例:
// 定義策略介面,宣告了策略的演算法方法 type Strategy interface { algorithm() } // 定義具體策略實現介面 type ConcreteStrategyA struct{} func (c *ConcreteStrategyA) algorithm() { fmt.Println("Executing Algorithm A") } // 定義上下文環境,包含策略介面型別的欄位 type Context struct { strategy Strategy } // 上下文環境執行策略的方法 func (c *Context) executeStrategy() { c.strategy.algorithm() } func main() { context := &Context{} strategyA := &ConcreteStrategyA{} context.strategy = strategyA // 設定策略 context.executeStrategy() // 執行策略 }
6. 介面卡模式(Adapter Pattern)
特點:使不相容介面能一起工作。
優點:增加相容性,客戶端程式碼無需修改。
缺點:系統複雜,可能引入效能開銷。
應用場景:系統整合、第三方庫整合等。
程式碼示例:
// 定義客戶端期望的介面 type Target interface { request() } // 定義一個已經存在的類,有自己的介面 type Adaptee struct{} func (a *Adaptee) specificRequest() { fmt.Println("Adaptee performs a specific request") } // 定義介面卡,作為Target介面和Adaptee類之間的橋樑 type Adapter struct { adaptee *Adaptee } func (a *Adapter) request() { if a.adaptee != nil { a.adaptee.specificRequest() // 委託呼叫Adaptee的方法 } } func main() { adaptee := &Adaptee{} adapter := &Adapter{adaptee: adaptee} var target Target = adapter // 客戶端透過介面卡使用Adaptee target.request() }
7. 代理模式(Proxy Pattern)
特點:為另一個物件提供代替或佔位符,控制訪問。
優點:降低耦合度,增加可控性,程式碼可擴充套件。
缺點:增加系統複雜性,可能引入效能開銷。
應用場景:訪問控制、延遲初始化、遠端代理等。
程式碼示例:
// 定義主題介面,宣告了請求方法 type Subject interface { request() } // 定義真實主題,實現了主題介面 type RealSubject struct{} func (r *RealSubject) request() { fmt.Println("Real Subject") } // 定義代理主題,包含對真實主題的引用 type Proxy struct { realSubject *RealSubject } func (p *Proxy) request() { if p.realSubject == nil { p.realSubject = &RealSubject{} // 如果沒有真實主題,則建立一個 } p.realSubject.request() // 呼叫真實主題的請求方法 }
8. 命令模式(Command Pattern)
特點:將請求或操作封裝為物件,解耦傳送者和接收者。
優點:降低耦合度,增加操作靈活性,易於擴充套件。
缺點:可能產生大量命令類。
應用場景:事務處理、撤銷操作、日誌請求等。
程式碼示例:
// 定義命令介面,宣告了執行方法 type Command interface { Execute() } // 定義接收者,將執行命令的實際請求 type Receiver struct{} func (r *Receiver) Action() { fmt.Println("Receiver: Action") } // 定義具體命令,實現命令介面,包含接收者的引用 type ConcreteCommand struct { receiver *Receiver } func (c *ConcreteCommand) Execute() { c.receiver.Action() // 執行接收者的操作 } // 定義呼叫者,負責呼叫命令物件的執行方法 type Invoker struct { command Command } func (i *Invoker) Invoke() { i.command.Execute() // 執行命令 } func main() { receiver := &Receiver{} command := &ConcreteCommand{receiver: receiver} // 建立具體命令物件,並注入接收者 invoker := &Invoker{command: command} // 建立呼叫者物件,並注入具體命令物件 invoker.Invoke() // 呼叫者執行命令 }
9. 組合模式(Composite Pattern)
特點:將物件組合成樹狀結構,一致對待單個物件和組合。
優點:簡化客戶端程式碼,更好的層次結構表示。
缺點:設計複雜,需要合理設計介面和類。
應用場景:檔案系統、組織結構、GUI元件等。
程式碼示例:
// 定義元件介面,作為組合中物件的一致性協議 type Component interface { Operation() Add(Component) Remove(Component) GetChild(int) Component } // 定義葉節點,實現元件介面 type Leaf struct { name string } func (l *Leaf) Operation() { fmt.Println("Leaf:", l.name) } func (l *Leaf) Add(c Component) { fmt.Println("Cannot add to a leaf") } func (l *Leaf) Remove(c Component) { fmt.Println("Cannot remove from a leaf") } func (l *Leaf) GetChild(i int) Component { return nil } // 定義組合節點,實現元件介面 type Composite struct { name string Children []Component } func (c *Composite) Operation() { fmt.Println("Composite:", c.name) for _, child := range c.Children { child.Operation() } } func (c *Composite) Add(component Component) { c.Children = append(c.Children, component) } func (c *Composite) Remove(component Component) { for i, child := range c.Children { if child == component { c.Children = append(c.Children[:i], c.Children[i+1:]...) break } } } func (c *Composite) GetChild(i int) Component { if i < 0 || i >= len(c.Children) { return nil } return c.Children[i] } func main() { leafA := &Leaf{name: "Leaf A"} leafB := &Leaf{name: "Leaf B"} composite := &Composite{name: "Composite Root"} composite.Add(leafA) // 向組合中新增葉節點A composite.Add(leafB) // 向組合中新增葉節點B composite.Operation() //
10. 迭代器模式(Iterator Pattern)
特點:順序訪問聚合物件元素,不暴露內部表示。
優點:抽象化集合訪問,支援多種遍歷方式,增加靈活性。
缺點:增加系統複雜性,需要額外程式碼實現迭代器。
應用場景:遍歷集合、數據結構、資料庫查詢等。
程式碼示例:
// 定義迭代器介面,宣告了遍歷集合的方法 type Iterator interface { Next() bool // 移動到下一個元素 Current() interface{} // 返回當前元素 } // 定義具體迭代器實現介面 type ConcreteIterator struct { items []string // 儲存聚合物件的元素列表 index int // 當前迭代到的元素索引 } func (c *ConcreteIterator) Next() bool { if c.index < len(c.items) { c.index++ return true } return false } func (c *ConcreteIterator) Current() interface{} { if c.index > 0 && c.index <= len(c.items) { return c.items[c.index-1] } return nil } // 定義聚合物件介面,宣告了建立迭代器的方法 type Aggregate interface { CreateIterator() Iterator // 建立並返回迭代器 } // 定義具體聚合物件實現介面 type ConcreteAggregate struct { items []string // 聚合物件儲存的元素列表 } func (a *ConcreteAggregate) CreateIterator() Iterator { return &ConcreteIterator{items: a.items, index: 0} // 返回一個新的迭代器例項 } func main() { aggregate := &ConcreteAggregate{items: []string{"Item1", "Item2", "Item3"}} iterator := aggregate.CreateIterator() // 使用聚合物件建立迭代器 // 使用迭代器遍歷聚合物件中的所有元素 for iterator.Next() { fmt.Println(iterator.Current()) } }
這些設計模式是軟體工程中常用的解決方案,可以幫助開發者提高程式碼的可重用性、可讀性和可靠性。