类图ITesttest(): voidtestImpl1test(): voidtestImpl2test(): voidtestFactorycreate(): ITest1 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
| type Product interface { Use() }
type productA struct { Product }
type productB struct { Product }
func (p *productA) Use() { fmt.Println("ProductA") }
func (p *productB) Use() { fmt.Println("ProductB") }
func ProductFactory(name string) Product { switch name { case "A": return &productA{} case "B": return &productB{} default: return nil } }
func main() { fmt.Println("Hello world")
product := ProductFactory("A") product.Use() product = ProductFactory("B") product.Use() }
|
2. 抽象工厂模式
最为抽象最具一般性,向客户端提供一个接口,使客户端在不必指定实例的具体类型的情况下创建多个实例族的实例对象。
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| type AbstractFactory interface { CreateProduct(name string) Product CreateWorker(name string) Worker }
type Product interface { Use() }
type productA struct { Product }
type productB struct { Product }
func (p *productA) Use() { fmt.Println("productA") }
func (p *productB) Use() { fmt.Println("productB") }
type ProductFactory struct{}
func (f *ProductFactory) CreateProduct(name string) Product { if name == "A" { return &productA{} } else if name == "B" { return &productB{} } return nil }
func (f *ProductFactory) CreateWorker(name string) Worker { return nil }
type Worker interface { Work() }
type workerA struct { Worker }
type workerB struct { Worker }
func (w *workerA) Work() { fmt.Println("workerA") }
func (w *workerB) Work() { fmt.Println("workerB") }
type WorkerFactory struct{}
func (f *WorkerFactory) CreateWorker(name string) Worker { if name == "A" { return &workerA{} } else if name == "B" { return &workerB{} } return nil }
func (f *WorkerFactory) CreateProduct(name string) Product { return nil }
func GetFactory(factoryType string) AbstractFactory { if factoryType == "product" { return &ProductFactory{} } else if factoryType == "worker" { return &WorkerFactory{} } return nil }
func main() { productFactory := GetFactory("product") productFactory.CreateProduct("A").Use() productFactory.CreateProduct("B").Use() workerFactory := GetFactory("worker") workerFactory.CreateWorker("A").Work() workerFactory.CreateWorker("B").Work() }
|
3. 单例模式
单例模式一般是用来让整个进程只有一个,一般是管理类。进程只有一个,再多线程情况下就需要考虑线程安全。常见的单例模式一般分为懒汉模式和饿汉模式。
懒汉模式
顾名思义,懒,就是用的时候才建立,不用不建立。分为线程安全的实现和非线程安全的实现,线程安全的实现会影响性能。一般由于两种线程安全的实现。
饿汉模式
开场就饿,进程开始就创建。默认就是线程安全的,但是要考虑头文件包含导致的多次创建。并且由于进程起来就创建,可能比较占用性能。
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
| type LasySingleton struct{}
var instance *LasySingleton
func GetInstance() *LasySingleton { if instance == nil { instance = new(LasySingleton) } return instance }
type SafeSingleton struct{}
var safeInstance *SafeSingleton var once sync.Once
func GetSafeInstance() *SafeSingleton { once.Do(func() { safeInstance = new(SafeSingleton) }) return safeInstance }
type HungrySingleton struct{}
var hungrySingleton *HungrySingleton = new(HungrySingleton)
func GetHungrySingleton() *HungrySingleton { return hungrySingleton }
func main() { instance1 := GetInstance() instance2 := GetInstance() if instance1 == instance2 { println("instance1 == instance2") }
instance3 := GetSafeInstance() instance4 := GetSafeInstance() if instance3 == instance4 { println("instance3 == instance4") }
instance5 := GetHungrySingleton() instance6 := GetHungrySingleton() if instance5 == instance6 { println("instance5 == instance6") } }
|
4. 建造者模式
- 将复杂对象的构建与其表示分开,使同样的构建过程可以创建不同的表示。
简单来说,存在一个厨师帮你构建一顿饭,包含一个个单独的菜组合。价格和列表不是厨师需要提供的,是饭菜(菜单)提供的。厨师就是建造者,需要的实例时饭菜。需要价格和列表找饭菜要!!!
- 主要用于将一个一个基础的实现,使用建造者进行构建成一个对外接口类
- 建造者只负责处理复杂的构建,需要的能力时从对外接口类获取
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| type item interface { GetName() string GetPrice() float64 }
type burger struct { price float64 name string }
func (b *burger) GetName() string { return b.name }
func (b *burger) GetPrice() float64 { return b.price }
type drink struct { price float64 name string }
func (d *drink) GetName() string { return d.name }
func (d *drink) GetPrice() float64 { return d.price }
type Meal struct { items []item }
func (m *Meal) addItem(item item) { m.items = append(m.items, item) }
func (m *Meal) GetCost() float64 { var cost float64 for _, item := range m.items { cost += item.GetPrice() } return cost }
func (m *Meal) GetItems() []string { var items []string for _, item := range m.items { items = append(items, item.GetName()) } return items }
type MealBuilder struct{}
func (b *MealBuilder) CreateMealA() Meal { meal := Meal{} meal.addItem(&burger{price: 10, name: "burger"}) meal.addItem(&drink{price: 5, name: "drink"}) return meal }
func (b *MealBuilder) CreateMealB() Meal { meal := Meal{} meal.addItem(&burger{price: 10, name: "burger"}) meal.addItem(&burger{price: 10, name: "burger"}) meal.addItem(&drink{price: 5, name: "drink"}) meal.addItem(&drink{price: 5, name: "drink"}) return meal }
func main() { builder := MealBuilder{} meal := builder.CreateMealA() fmt.Printf("Meal A: %s, cost: %.2f\n", meal.GetItems(), meal.GetCost()) meal = builder.CreateMealB() fmt.Printf("Meal B: %s, cost: %.2f\n", meal.GetItems(), meal.GetCost()) }
|
5. 原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
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
| type Painter interface { Clone() Painter DrawCrcle() SetColor(color string) GetColor() string }
type PainterA struct { color string }
func (p *PainterA) Clone() Painter { return &PainterA{p.color} }
func (p *PainterA) DrawCrcle() { fmt.Println("PainterA DrawCircle") }
func (p *PainterA) SetColor(color string) { p.color = color }
func (p *PainterA) GetColor() string { return p.color }
func main() { a := PainterA{} a.SetColor("red") b := a.Clone() fmt.Println(b.GetColor()) b.SetColor("blue") fmt.Println(a.GetColor()) }
|
B.结构型模式
6. 适配器模式
- 关键在于兼容,将原有接口兼容当前使用
- 兼容了当前框架的操作
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
| type module struct { a int }
func (m *module) start() { m.a = 1 }
func (m *module) stop() { m.a = 0 }
type moduleAdapter struct { module }
func (m *moduleAdapter) init() { m.start() } func (m *moduleAdapter) uninit() { m.stop() }
func main() { m := moduleAdapter{} m.init() m.uninit() }
|
7. 组合(部分-整体)模式
将对象组合成树形结构以表示“部分-整体”的层次结构
8. 装饰器模式
动态给对象添加额外职责,比通过生成子类来增加功能更加灵活
- 关键在于加强,原始类的所有接口都进行了实现
- 比如存在一个接口实现了非线程安全的一些方法,使用一个装饰器将所有的方法变成线程安全的调用
- 比如存在一个接口实现了画图,使用一个装饰器将画的图染成红色
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
| type Painter interface { DrawCircle() DrawRectangle() }
type PainterA struct { Painter }
type PainterDecorator struct { A PainterA Painter }
func (p *PainterA) DrawCircle() { fmt.Println("PainterA DrawCircle") }
func (p *PainterA) DrawRectangle() { fmt.Println("PainterA DrawRectangle") }
func (p *PainterDecorator) DrawCircle() { fmt.Println("Use red color") p.A.DrawCircle() }
func (p *PainterDecorator) DrawRectangle() { fmt.Println("Use red color") p.A.DrawRectangle() }
func main() { painter := &PainterA{} painter.DrawCircle() painter.DrawRectangle() painter1 := &PainterDecorator{ A: PainterA{}, } painter1.DrawCircle() painter1.DrawRectangle() }
|
9. 代理模式
- 关键在于隔离,不直接访问原始对象
- 和装饰器不同的时,代理模式更多的是封装原始接口,但不改变原始接口的能力
- 比如加上日志打印或者初始化操作,这些并不改变原始接口的能力,并且可以将原始类的实现细节隐藏
- 装饰器并不隐藏原始实现
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
| type painter interface { init() drawCircle() }
type painterA struct { painter }
type PainterProxy struct { a painterA }
func (p *painterA) init() { fmt.Println("painterA init") }
func (p *painterA) drawCircle() { fmt.Println("painterA DrawCircle") }
func (p *PainterProxy) DrawCircle() { if p.a.painter == nil { p.a = painterA{} p.a.init() } p.a.drawCircle() }
func main() { p := PainterProxy{} p.DrawCircle() }
|
10. 享元模式
运用共享技术有效地支持大量的细粒度对象
11. 外观(门面)模式
为一组接口提供一个一致的接口,体现了DIP和LoD原则
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
| type drawer interface { draw() }
type circle struct { drawer }
func (c *circle) draw() { fmt.Println("draw circle") }
type square struct { drawer }
func (s *square) draw() { fmt.Println("draw square") }
type Facade struct { circleDrawer circle squareDrawer square }
func (f *Facade) DrawCircle() { if f.circleDrawer.drawer == nil { f.circleDrawer = circle{} } f.circleDrawer.draw() }
func (f *Facade) DrawSquare() { if f.squareDrawer.drawer == nil { f.squareDrawer = square{} } f.squareDrawer.draw() }
func main() { facade := &Facade{} facade.DrawCircle() facade.DrawSquare() }
|
12. 桥接模式
将抽象部分与其实现部分分离,使它们都可以独立变化,可实现多角度分类
C.行为型模式
13. 策略模式
- 定义一种策略,比如从A到B
- 使用多个方法进行实现此策略,比如飞机、汽车、走路
- 使用者自己选择方法,调用同一个策略进行执行
- 本质是封装公共的调用逻辑和方法,如超市的接口方法为算要付多少钱,但是存在不同的策略,如打几折,满多少送多少等
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
| type Strategy interface { run() }
type StrategyA struct { Strategy }
type StrategyB struct { Strategy }
func (s *StrategyA) run() { fmt.Println("StrategyA") }
func (s *StrategyB) run() { fmt.Println("StrategyB") }
func RunStrategy(s Strategy) { s.run() }
func main() { strategy.RunStrategy(&strategy.StrategyA{}) strategy.RunStrategy(&strategy.StrategyB{}) }
|
14. 模板方法模式
定义一个操作中算法的骨架,而将一些具体步骤延迟到子类
- 可以认为是一个模板类实现了公共的逻辑,子类只需要实现非公用逻辑即可
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
| type Product interface { Use() Print() }
type ProductTemplate struct { Name string Product }
type ProductA struct { ProductTemplate }
type ProductB struct { ProductTemplate }
func (p *ProductTemplate) Print() { fmt.Println("name", p.Name) }
func (p *ProductA) Use() { fmt.Println("ProductA use") }
func (p *ProductB) Use() { fmt.Println("ProductB use") }
func main() { p := ProductA{ ProductTemplate: ProductTemplate{ Name: "ProductA", }, } p.Use() p.Print() p1 := ProductB{ ProductTemplate: ProductTemplate{ Name: "ProductB", }} p1.Use() p1.Print() }
|
15. 观察者模式(发布-订阅模式)
定义一种一对多的依赖关系,让多个观察者对象同时监听某一个通知者对象
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
| type Product struct { Name string observerList []Observer }
type Observer interface { Update(product *Product) }
func (p *Product) AddObserver(observer Observer) { p.observerList = append(p.observerList, observer) }
func (p *Product) SetName(name string) { p.Name = name for _, observer := range p.observerList { observer.Update(p) } }
type ObserverA struct { Observer }
func (o *ObserverA) Update(product *Product) { fmt.Printf("ObserverA: %s\n", product.Name) }
type ObserverB struct { Observer }
func (o *ObserverB) Update(product *Product) { fmt.Printf("ObserverB: %s\n", product.Name) }
func main() { product := &Product{} observerA := &ObserverA{} observerB := &ObserverB{} product.AddObserver(observerA) product.AddObserver(observerB) product.SetName("productA") product.SetName("productB") }
|
16. 迭代器模式
提供顺序访问一个聚合中元素的方法。不常用,因为语言本身已内置
17. 职责链模式
使多个对象都有机会获得机会处理请求。这些对象连成一条链。减少请求得与接收者的耦合。如过滤器
18. 命令模式
将请求封装成一个对象,以使你可用不同的请求对客户端进行参数化;可对请求进行排除、记录日志、或撤销操作
19. 备忘录模式
在不破坏封装的前提下捕获一个对象的内部状态,并在该对象外部保存此状态
20. 状态模式
当一个状态改变时,允许改变其行为,看其来像是改变了其类。(将复杂的条件判断转移到多个小类中)
21. 访问者模式
表示一个作用于某对象结构中的各元素的操作。把数据处理与数据结构分开
22. 解释器模式
对一个语言定义一个文法的表示,并定义一个解释器,来解释语言中的句子,如正则表达式,浏览器。通过解释执行
23. 中介者(调停者)模式
用一个中介对象来封装一系列的对象交互。应用于星形结构的对象关系中
微信支付
支付宝