gof23创建类模式(golang版)
区块链的征程已开启
github欢迎star
https://github.com/transienth...
单例模式
Java中的单例模式的实现可以有饿汉式、懒汉式、双锁、静态内部类、枚举等形式,在go中如何实现单例呢,先来最简单的形式,不考虑高并发的情况下,应该怎样实现
package main var m *Singleton type Singleton struct { } func GetInstance() *Singleton { if m == nil { m = &Singleton{} } return m }
问题就是并发的时候会取到多个对象,解决方案
加锁
package main import ( "sync" ) var instance *Singleton var lock *sync.Mutex = &sync.Mutex{} type Singleton struct { } func GetInstance() *Singleton { lock.Lock() defer lock.Unlock() if instance != nil { instance = &Singleton{} } return instance }
go语言特性,支持一种更为方便的加锁:sync.Once
package main import ( "sync" ) var ( instance *Singleton lock *sync.Mutex = &sync.Mutex{} once sync.Once ) type Singleton struct { } func GetInstance() *Singleton { once.Do(func() { instance = &Singleton{} }) return instance }
简单工厂模式
简单工厂模式生产的产品是固定的,要生产苹果,就有个MakeApple()的方法;要生产橘子,就有个MakeOrange()的方法
package creation type FruitFactory interface { makeApple() Apple makeOrange() Orange } type Apple struct { desc string } type Orange struct { desc string } type Factory struct { } func (this Factory) MakeApple() Apple { return Apple{"我是一个苹果"} } func (this Factory) MakeOrange() Orange { return Orange{"我是一个橘子"} }
client
package main import ( "gof23/creation" "fmt" ) func main() { factory := creation.Factory{} apple := factory.MakeApple() orange := factory.MakeOrange() fmt.Println(apple) fmt.Println(orange) }
工厂方法模式
工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
package creation type FruitPicker interface { MakeFruit() Fruit } type Fruit interface { } type Banana struct { desc string } type BananaPicker struct { } func (this BananaPicker) MakeFruit(fruitName string) Fruit { switch fruitName { case "banana": return Banana{"我是一根香蕉"} default: return Apple{"可能我是一个苹果吧"} } }
client
package main import ( "gof23/creation" "fmt" ) func main() { bananaPicker := creation.BananaPicker{} banana := bananaPicker.MakeFruit("banana") fmt.Println(banana) }
抽象工厂模式
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。
为了更清晰地理解工厂方法模式,需要先引入两个概念:
产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
产品族 :在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。
当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。
抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。
抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。
抽象工厂模式包含如下角色:
- AbstractFactory:抽象工厂
- ConcreteFactory:具体工厂
- AbstractProduct:抽象产品
- Product:具体产品
抽象工厂模式侧重于产品族
package creation type PlantFactory interface { MakePlant() Plant MakePicker() Picker } type Plant interface { } type Picker interface { } type PearFactory struct { } type Pear struct { desc string } type PearPicker struct { desc string } func (this PearFactory) MakePlant() Plant { return Pear{"我是一个梨"} } func (this PearFactory) MakePicker() Picker { return PearPicker{"采摘一个梨"} }
client
package main import ( "gof23/creation" "fmt" ) func main() { factory := creation.PearFactory{} pearPicker := factory.MakePicker() pear := factory.MakePlant() fmt.Println(pear) fmt.Println(pearPicker) }
建造者模式
建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式属于对象创建型模式。根据中文翻译的不同,建造者模式又可以称为生成器模式。
建造者模式包含如下角色:
- Builder:抽象建造者
- ConcreteBuilder:具体建造者
- Director:指挥者
- Product:产品角色
package creation type Character struct { Name string Arms string } func (p *Character) SetName(name string) { p.Name = name } func (p *Character) SetArms(arms string) { p.Arms = arms } func (p Character) GetArms() string { return p.Arms } func (p Character) GetName() string { return p.Name } type Builder interface { SetName(name string) Builder SetArms(arms string) Builder Build() *Character } type CharacterBuilder struct { character *Character } func (p *CharacterBuilder) SetName(name string) Builder { if p.character == nil { p.character = &Character{} } p.character.SetName(name) return p } func (p *CharacterBuilder) SetArms(arms string) Builder { if p.character == nil { p.character = &Character{} } p.character.SetArms(arms) return p } func (p *CharacterBuilder) Build() *Character { return p.character } type Director struct { Builder Builder } func (p Director) Create(name string, arms string) *Character { return p.Builder.SetName(name).SetArms(arms).Build() }
client
package main import ( "fmt" "gof23/creation" ) func main() { var builder creation.Builder = &creation.CharacterBuilder{} var director *creation.Director = &creation.Director {builder} var character *creation.Character = director.Create("loader", "AK47") fmt.Println(character.GetName() + "," + character.GetArms()) }