设计模式-创建型-go实现版
介绍
工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法模式让一个类的实例化延迟到其子类中进行。
抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。
建造者模式(Builder Pattern):将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并通过复制这些原型来创建新的对象。
使用场景
工厂方法模式:定义一个用于创建对象的接口,但由子类决定要实例化的类是哪一个,适用于需要动态地创建对象的场景。
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类,适用于需要创建一系列相关对象的场景。
单例模式:确保一个类只有一个实例,并提供全局访问点,适用于需要确保只有一个实例存在的场景。
原型模式:通过复制已有对象来创建新对象,而无需知道任何创建的细节,适用于需要快速创建新对象的场景。
建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,适用于需要创建复杂对象的场景。
系统的复杂性:如果系统非常复杂,那么可能需要使用创建型设计模式来帮助管理对象的创建和组织。
对象的数量:如果需要创建大量的对象,那么可以考虑使用创建型设计模式来减少对象的创建和销毁次数。
对象的依赖关系:如果对象之间存在复杂的依赖关系,那么可以考虑使用创建型设计模式来处理这些依赖关系。
系统的扩展性:选择合适的创建型设计模式可以使系统更易于扩展和维护。
实现例子
工厂方法模式
package main
import "fmt"
// 定义接口
type Product interface {
GetName() string
}
// 定义结构体A
type ProductA struct{
AxxProti AAA
}
func (p *ProductA) GetName() string {
return "ProductA"
}
// 定义结构体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() {
// 创建工厂A
factoryA := &FactoryA{}
// 通过工厂A创建产品A
productA := factoryA.Create()
fmt.Println(productA.GetName()) // 输出:ProductA
// 创建工厂B
factoryB := &FactoryB{}
// 通过工厂B创建产品B
productB := factoryB.Create()
fmt.Println(productB.GetName()) // 输出:ProductB
}
Product
接口定义了产品的方法,ProductA
和 ProductB
结构体分别实现了 Product
接口。Factory
接口定义了工厂的方法,FactoryA
和 FactoryB
结构体分别实现了 Factory
接口,其中 FactoryA
可以用于创建 ProductA
,FactoryB
可以用于创建 ProductB
。main
函数中,我们创建了 FactoryA
和 FactoryB
两个工厂,然后通过它们分别创建了 ProductA
和 ProductB
两个产品。由于每个工厂只能创建对应的产品,因此输出的结果也不同。抽象工厂模式
package main
import "fmt"
// 定义接口1
type Button interface {
Paint()
}
// 定义接口2
type Label interface {
Paint()
}
// 定义工厂接口
type GUIFactory interface {
CreateButton() Button
CreateLabel() Label
}
// 定义具体按钮结构体
type WindowsButton struct{}
func (b *WindowsButton) Paint() {
fmt.Println("Windows Button")
}
type MacButton struct{}
func (b *MacButton) Paint() {
fmt.Println("Mac Button")
}
// 定义具体标签结构体
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() {
// 创建Windows GUI工厂
windowsFactory := &WindowsGUIFactory{}
windowsButton := windowsFactory.CreateButton()
windowsLabel := windowsFactory.CreateLabel()
windowsButton.Paint() // 输出:Windows Button
windowsLabel.Paint() // 输出:Windows Label
// 创建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())
}