設(shè)計(jì)模式-創(chuàng)建型-go實(shí)現(xiàn)版
介紹
工廠方法模式(Factory Method Pattern):定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪個(gè)類。工廠方法模式讓一個(gè)類的實(shí)例化延遲到其子類中進(jìn)行。
抽象工廠模式(Abstract Factory Pattern):提供一個(gè)接口,用于創(chuàng)建相關(guān)或依賴對(duì)象的家族,而不需要明確指定具體類。
單例模式(Singleton Pattern):確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問(wèn)點(diǎn)。
建造者模式(Builder Pattern):將一個(gè)復(fù)雜對(duì)象的構(gòu)建過(guò)程與其表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。
原型模式(Prototype Pattern):使用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并通過(guò)復(fù)制這些原型來(lái)創(chuàng)建新的對(duì)象。
使用場(chǎng)景
工廠方法模式:定義一個(gè)用于創(chuàng)建對(duì)象的接口,但由子類決定要實(shí)例化的類是哪一個(gè),適用于需要?jiǎng)討B(tài)地創(chuàng)建對(duì)象的場(chǎng)景。
抽象工廠模式:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無(wú)需指定它們具體的類,適用于需要?jiǎng)?chuàng)建一系列相關(guān)對(duì)象的場(chǎng)景。
單例模式:確保一個(gè)類只有一個(gè)實(shí)例,并提供全局訪問(wèn)點(diǎn),適用于需要確保只有一個(gè)實(shí)例存在的場(chǎng)景。
原型模式:通過(guò)復(fù)制已有對(duì)象來(lái)創(chuàng)建新對(duì)象,而無(wú)需知道任何創(chuàng)建的細(xì)節(jié),適用于需要快速創(chuàng)建新對(duì)象的場(chǎng)景。
建造者模式:將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示,適用于需要?jiǎng)?chuàng)建復(fù)雜對(duì)象的場(chǎng)景。
系統(tǒng)的復(fù)雜性:如果系統(tǒng)非常復(fù)雜,那么可能需要使用創(chuàng)建型設(shè)計(jì)模式來(lái)幫助管理對(duì)象的創(chuàng)建和組織。
對(duì)象的數(shù)量:如果需要?jiǎng)?chuàng)建大量的對(duì)象,那么可以考慮使用創(chuàng)建型設(shè)計(jì)模式來(lái)減少對(duì)象的創(chuàng)建和銷毀次數(shù)。
對(duì)象的依賴關(guān)系:如果對(duì)象之間存在復(fù)雜的依賴關(guān)系,那么可以考慮使用創(chuàng)建型設(shè)計(jì)模式來(lái)處理這些依賴關(guān)系。
系統(tǒng)的擴(kuò)展性:選擇合適的創(chuàng)建型設(shè)計(jì)模式可以使系統(tǒng)更易于擴(kuò)展和維護(hù)。
實(shí)現(xiàn)例子
工廠方法模式
package main
import "fmt"
// 定義接口
type Product interface {
GetName() string
}
// 定義結(jié)構(gòu)體A
type ProductA struct{
AxxProti AAA
}
func (p *ProductA) GetName() string {
return "ProductA"
}
// 定義結(jié)構(gòu)體B
type ProductB struct{}
func (p *ProductB) GetName() string {
return "ProductB"
}
// 定義工廠接口
type Factory interface {
Create() Product
}
// 定義工廠A
type FactoryA struct{}
func (f *FactoryA) Create() Product {
return &ProductA{}
}
// 定義工廠B
type FactoryB struct{}
func (f *FactoryB) Create() Product {
return &ProductB{}
}
func main() {
// 創(chuàng)建工廠A
factoryA := &FactoryA{}
// 通過(guò)工廠A創(chuàng)建產(chǎn)品A
productA := factoryA.Create()
fmt.Println(productA.GetName()) // 輸出:ProductA
// 創(chuàng)建工廠B
factoryB := &FactoryB{}
// 通過(guò)工廠B創(chuàng)建產(chǎn)品B
productB := factoryB.Create()
fmt.Println(productB.GetName()) // 輸出:ProductB
}
Product 接口定義了產(chǎn)品的方法,ProductA 和 ProductB 結(jié)構(gòu)體分別實(shí)現(xiàn)了 Product 接口。Factory 接口定義了工廠的方法,FactoryA 和 FactoryB 結(jié)構(gòu)體分別實(shí)現(xiàn)了 Factory 接口,其中 FactoryA 可以用于創(chuàng)建 ProductA,FactoryB 可以用于創(chuàng)建 ProductB。main 函數(shù)中,我們創(chuàng)建了 FactoryA 和 FactoryB 兩個(gè)工廠,然后通過(guò)它們分別創(chuàng)建了 ProductA 和 ProductB 兩個(gè)產(chǎn)品。由于每個(gè)工廠只能創(chuàng)建對(duì)應(yīng)的產(chǎn)品,因此輸出的結(jié)果也不同。抽象工廠模式
package main
import "fmt"
// 定義接口1
type Button interface {
Paint()
}
// 定義接口2
type Label interface {
Paint()
}
// 定義工廠接口
type GUIFactory interface {
CreateButton() Button
CreateLabel() Label
}
// 定義具體按鈕結(jié)構(gòu)體
type WindowsButton struct{}
func (b *WindowsButton) Paint() {
fmt.Println("Windows Button")
}
type MacButton struct{}
func (b *MacButton) Paint() {
fmt.Println("Mac Button")
}
// 定義具體標(biāo)簽結(jié)構(gòu)體
type WindowsLabel struct{}
func (l *WindowsLabel) Paint() {
fmt.Println("Windows Label")
}
type MacLabel struct{}
func (l *MacLabel) Paint() {
fmt.Println("Mac Label")
}
// 定義具體工廠
type WindowsGUIFactory struct{}
func (f *WindowsGUIFactory) CreateButton() Button {
return &WindowsButton{}
}
func (f *WindowsGUIFactory) CreateLabel() Label {
return &WindowsLabel{}
}
type MacGUIFactory struct{}
func (f *MacGUIFactory) CreateButton() Button {
return &MacButton{}
}
func (f *MacGUIFactory) CreateLabel() Label {
return &MacLabel{}
}
func main() {
// 創(chuàng)建Windows GUI工廠
windowsFactory := &WindowsGUIFactory{}
windowsButton := windowsFactory.CreateButton()
windowsLabel := windowsFactory.CreateLabel()
windowsButton.Paint() // 輸出:Windows Button
windowsLabel.Paint() // 輸出:Windows Label
// 創(chuàng)建Mac GUI工廠
macFactory := &MacGUIFactory{}
macButton := macFactory.CreateButton()
macLabel := macFactory.CreateLabel()
macButton.Paint() // 輸出:Mac Button
macLabel.Paint() // 輸出:Mac Label
}
單例模式
package singleton
import "sync"
type singleton struct{}
var instance *singleton
var once sync.Once
func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}
建造者模式
package builder
type Builder interface {
SetName(name string) Builder
SetAge(age int) Builder
Build() *Person
}
type Person struct {
Name string
Age int
}
type PersonBuilder struct {
person *Person
}
func NewPersonBuilder() *PersonBuilder {
return &PersonBuilder{person: &Person{}}
}
func (b *PersonBuilder) SetName(name string) Builder {
b.person.Name = name
return b
}
func (b *PersonBuilder) SetAge(age int) Builder {
b.person.Age = age
return b
}
func (b *PersonBuilder) Build() *Person {
return b.person
}
原型模式
package prototype
import (
"fmt"
)
type Prototype interface {
Clone() Prototype
GetName() string
}
type ConcretePrototype struct {
name string
}
func (p *ConcretePrototype) Clone() Prototype {
return &ConcretePrototype{name: p.name}
}
func (p *ConcretePrototype) GetName() string {
return p.name
}
func main() {
prototype := &ConcretePrototype{name: "prototype"}
clone := prototype.Clone()
fmt.Println(clone.GetName())
}
