區(qū)塊鏈的征程已開啟
單例模式
Java中的單例模式的實現(xiàn)可以有餓漢式、懶漢式、雙鎖讳窟、靜態(tài)內(nèi)部類让歼、枚舉等形式,在go中如何實現(xiàn)單例呢挪钓,先來最簡單的形式是越,不考慮高并發(fā)的情況下,應(yīng)該怎樣實現(xiàn)
package main
var m *Singleton
type Singleton struct {
}
func GetInstance() *Singleton {
if m == nil {
m = &Singleton{}
}
return m
}
問題就是并發(fā)的時候會取到多個對象碌上,解決方案
加鎖
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
}
簡單工廠模式
簡單工廠模式生產(chǎn)的產(chǎn)品是固定的,要生產(chǎn)蘋果馏予,就有個MakeApple()的方法天梧;要生產(chǎn)橘子,就有個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)又稱為工廠模式霞丧,也叫虛擬構(gòu)造器(Virtual Constructor)模式或者多態(tài)工廠(Polymorphic Factory)模式呢岗,它屬于類創(chuàng)建型模式。在工廠方法模式中蛹尝,工廠父類負責定義創(chuàng)建產(chǎn)品對象的公共接口后豫,而工廠子類則負責生成具體的產(chǎn)品對象,這樣做的目的是將產(chǎn)品類的實例化操作延遲到工廠子類中完成突那,即通過工廠子類來確定究竟應(yīng)該實例化哪一個具體產(chǎn)品類挫酿。
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)
}
抽象工廠模式
在工廠方法模式中具體工廠負責生產(chǎn)具體的產(chǎn)品,每一個具體工廠對應(yīng)一種具體產(chǎn)品愕难,工廠方法也具有唯一性早龟,一般情況下,一個具體工廠中只有一個工廠方法或者一組重載的工廠方法猫缭。但是有時候我們需要一個工廠可以提供多個產(chǎn)品對象葱弟,而不是單一的產(chǎn)品對象。
為了更清晰地理解工廠方法模式猜丹,需要先引入兩個概念:
產(chǎn)品等級結(jié)構(gòu) :產(chǎn)品等級結(jié)構(gòu)即產(chǎn)品的繼承結(jié)構(gòu)芝加,如一個抽象類是電視機,其子類有海爾電視機射窒、海信電視機妖混、TCL電視機,則抽象電視機與具體品牌的電視機之間構(gòu)成了一個產(chǎn)品等級結(jié)構(gòu)轮洋,抽象電視機是父類制市,而具體品牌的電視機是其子類。
產(chǎn)品族 :在抽象工廠模式中弊予,產(chǎn)品族是指由同一個工廠生產(chǎn)的祥楣,位于不同產(chǎn)品等級結(jié)構(gòu)中的一組產(chǎn)品,如海爾電器工廠生產(chǎn)的海爾電視機、海爾電冰箱误褪,海爾電視機位于電視機產(chǎn)品等級結(jié)構(gòu)中责鳍,海爾電冰箱位于電冰箱產(chǎn)品等級結(jié)構(gòu)中。
當系統(tǒng)所提供的工廠所需生產(chǎn)的具體產(chǎn)品并不是一個簡單的對象兽间,而是多個位于不同產(chǎn)品等級結(jié)構(gòu)中屬于不同類型的具體產(chǎn)品時需要使用抽象工廠模式历葛。
抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形態(tài)。
抽象工廠模式與工廠方法模式最大的區(qū)別在于嘀略,工廠方法模式針對的是一個產(chǎn)品等級結(jié)構(gòu)恤溶,而抽象工廠模式則需要面對多個產(chǎn)品等級結(jié)構(gòu),一個工廠等級結(jié)構(gòu)可以負責多個不同產(chǎn)品等級結(jié)構(gòu)中的產(chǎn)品對象的創(chuàng)建 帜羊。當一個工廠等級結(jié)構(gòu)可以創(chuàng)建出分屬于不同產(chǎn)品等級結(jié)構(gòu)的一個產(chǎn)品族中的所有對象時咒程,抽象工廠模式比工廠方法模式更為簡單、有效率讼育。
抽象工廠模式(Abstract Factory Pattern):提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口帐姻,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式奶段,屬于對象創(chuàng)建型模式饥瓷。
抽象工廠模式包含如下角色:
- AbstractFactory:抽象工廠
- ConcreteFactory:具體工廠
- AbstractProduct:抽象產(chǎn)品
- Product:具體產(chǎn)品
抽象工廠模式側(cè)重于產(chǎn)品族
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):將一個復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示痹籍。
建造者模式是一步一步創(chuàng)建一個復(fù)雜的對象呢铆,它允許用戶只通過指定復(fù)雜對象的類型和內(nèi)容就可以構(gòu)建它們,用戶不需要知道內(nèi)部的具體構(gòu)建細節(jié)词裤。建造者模式屬于對象創(chuàng)建型模式刺洒。根據(jù)中文翻譯的不同鳖宾,建造者模式又可以稱為生成器模式吼砂。
建造者模式包含如下角色:
- Builder:抽象建造者
- ConcreteBuilder:具體建造者
- Director:指揮者
- Product:產(chǎn)品角色
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())
}