【笔记】Go语言设计模式的创建型模式

前言

Go语言设计模式的创建型模式学习笔记

单例模式

  • 保证一个类仅有一个实例,并提供一个访问它的全局访问点

饿汉式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

type apple struct{}

var singleApple *apple = new(apple)

func GetSingleApple() *apple {
return singleApple
}

func (apple) doSomething() {}

func main() {
var apple *apple = GetSingleApple()
apple.doSomething()
}

懒汉式

加锁的方式实现

直接加锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import "sync"

type apple struct{}

var singleApple *apple

var lock sync.Mutex

func GetSingleApple() *apple {
// 加锁
lock.Lock()
defer lock.Unlock()
if singleApple == nil {
singleApple = new(apple)
}
return singleApple
}

func (apple) doSomething() {}

func main() {
var apple *apple = GetSingleApple()
apple.doSomething()
}
判断标记再加锁
  • 直接加锁会导致性能降低
  • 通过判断标记再加锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
"sync"
"sync/atomic"
)

type apple struct{}

var singleApple *apple

var initialized uint32

var lock sync.Mutex

func GetSingleApple() *apple {
if atomic.LoadUint32(&initialized) == 1 {
return singleApple
} else {
// 加锁
lock.Lock()
defer lock.Unlock()
}
if singleApple == nil {
// 设置标记位为1
atomic.StoreUint32(&initialized, 1)
singleApple = new(apple)
}
return singleApple
}

func (apple) doSomething() {}

func main() {
var apple *apple = GetSingleApple()
apple.doSomething()
}

只执行一次的函数

  • 原理与判断标记再加锁相同,只不过进行了封装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
"sync"
)

type apple struct{}

var singleApple *apple

var once sync.Once

func GetSingleApple() *apple {
once.Do(func() {
singleApple = new(apple)
})
return singleApple
}

func (apple) doSomething() {}

func main() {
var apple *apple = GetSingleApple()
apple.doSomething()
}

简单工厂方法模式

  • 通过专门地定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

// Fruit 水果
type Fruit interface {
Show()
}

// Apple 苹果
type Apple struct{}

func (Apple) Show() {}

// FruitFactory 水果工厂
type FruitFactory struct{}

// NewFruit 生产水果
func (FruitFactory) NewFruit(name string) Fruit {
var fruit Fruit

switch name {
case "apple":
fruit = new(Apple)
}

return fruit
}

func main() {
var fruitFactory = new(FruitFactory)
var apple Fruit = fruitFactory.NewFruit("apple")
apple.Show()
}

工厂方法模式

  • 定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

// Fruit 水果
type Fruit interface {
Show()
}

// FruitFactory 水果工厂
type FruitFactory interface {
NewFruit() Fruit
}

// Apple 苹果
type Apple struct{}

func (Apple) Show() {}

// AppleFactory 苹果工厂
type AppleFactory struct{}

func (AppleFactory) NewFruit() Fruit {
return new(Apple)
}

func main() {
var fruitFactory FruitFactory = new(AppleFactory)
var apple = fruitFactory.NewFruit()
apple.Show()
}

抽象工厂方法模式

  • 提供一个创建一系列相关或者相互依赖的接口,而无需指定它们具体的类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package main

// Apple 苹果
type Apple interface {
ShowApple()
}

// Banana 香蕉
type Banana interface {
ShowBanana()
}

// FruitFactory 水果工厂
type FruitFactory interface {
NewApple() Apple
NewBanana() Banana
}

// ChineseApple 中国苹果
type ChineseApple struct{}

func (ChineseApple) ShowApple() {}

// JapaneseApple 日本苹果
type JapaneseApple struct{}

func (JapaneseApple) ShowApple() {}

// ChineseBanana 中国香蕉
type ChineseBanana struct{}

func (ChineseBanana) ShowBanana() {}

// JapaneseBanana 日本香蕉
type JapaneseBanana struct{}

func (JapaneseBanana) ShowBanana() {}

// ChineseFruitFactory 中国水果工厂
type ChineseFruitFactory struct{}

func (ChineseFruitFactory) NewApple() Apple {
return new(ChineseApple)
}

func (ChineseFruitFactory) NewBanana() Banana {
return new(ChineseBanana)
}

// JapaneseFruitFactory 日本水果工厂
type JapaneseFruitFactory struct{}

func (JapaneseFruitFactory) NewApple() Apple {
return new(JapaneseApple)
}

func (JapaneseFruitFactory) NewBanana() Banana {
return new(JapaneseBanana)
}

func main() {
// 中国苹果
var chineseFruitFactory FruitFactory = new(ChineseFruitFactory)
var chineseApple Apple = chineseFruitFactory.NewApple()
chineseApple.ShowApple()

// 日本香蕉
var japaneseFruitFactory FruitFactory = new(JapaneseFruitFactory)
var japaneseBanana Banana = japaneseFruitFactory.NewBanana()
japaneseBanana.ShowBanana()
}

原型模式

  • 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象

建造者模式

  • 将一个复杂的构建与其表示相分离,使得同样地构建过程可以创建不同的表示

完成

参考文献

哔哩哔哩——刘丹冰AceId