├── 01_简单工厂模式 ├── 1.10_简单工厂模式 │ ├── simplefactory.go │ └── simplefactory_test.go ├── 1.8_业务封装 │ ├── simplefactory.go │ └── simplefactory_test.go └── README.md ├── 02_策略模式 ├── 2.3_简单工厂实现 │ ├── strategy.go │ └── strategy_test.go ├── 2.4_策略模式(常规实现) │ ├── strategy.go │ └── strategy_test.go ├── 2.5_策略模式实现 │ ├── strategy.go │ └── strategy_test.go ├── 2.6_策略和简单工厂结合 │ ├── strategy.go │ └── strategy_test.go └── README.md ├── 03_单一职责原则 └── README.md ├── 04_开放封闭原则 └── README.md ├── 05_依赖倒转原则 └── README.md ├── 06_装饰模式 ├── 6.1_穿衣01 │ ├── decorator.go │ └── decorator_test.go ├── 6.2_穿衣02 │ ├── decorator.go │ └── decorator_test.go ├── 6.3_装饰模式(常规实现) │ ├── decorator.go │ └── decorator_test.go ├── 6.4_穿衣03 │ ├── decorator.go │ └── decorator_test.go └── README.md ├── 07_代理模式 ├── 7.2_没有代理的代码 │ ├── proxy.go │ └── proxy_test.go ├── 7.3_没有代理的代码 │ ├── proxy.go │ └── proxy_test.go ├── 7.4_符合实际的代码 │ ├── proxy.go │ └── proxy_test.go ├── 7.5_代理模式(常规实现) │ ├── proxy.go │ └── proxy_test.go └── README.md ├── 08_工厂方法 ├── 8.3_工厂模式实现 │ ├── factorymethod.go │ └── factorymethod_test.go ├── 8.5_雷锋工厂 │ ├── factorymethod.go │ └── factorymethod_test.go └── README.md ├── 09_原型模式 ├── 9.2_简历初步代码 │ ├── prototype.go │ └── prototype_test.go ├── 9.3_原型模式(常规代码) │ ├── prototype.go │ └── prototype_test.go ├── 9.4_简历的原型实现 │ ├── prototype.go │ └── prototype_test.go ├── 9.5_浅度复制和深度复制 │ ├── prototype.go │ └── prototype_test.go └── README.md ├── 10_模板方法 ├── 10.2_重复等于易做加难改 │ ├── templatemethod.go │ └── templatemethod_test.go ├── 10.3_提炼代码(模板方法) │ ├── templatemethod.go │ └── templatemethod_test.go ├── 10.3_提炼代码(策略模式) │ ├── templatemethod.go │ └── templatemethod_test.go ├── 10_4模板方法模式 │ ├── templatemethod.go │ └── templatemethod_test.go └── README.md ├── 11_迪米特法则 └── README.md ├── 12_外观模式 ├── 12.2_股民炒股代码 │ ├── facade.go │ └── facade_test.go ├── 12.3_投资资金代码 │ ├── facade.go │ └── facade_test.go ├── 12.4_外观模式 │ ├── facade.go │ └── facade_test.go └── README.md ├── 13_建造者模式 ├── 13.6_建造者模式 │ ├── builder.go │ └── builder_test.go ├── README.md └── 建造者模式(常规实现) │ ├── builder.go │ └── builder_test.go ├── 14_观察者模式 ├── 14.2_双向耦合代码 │ ├── obserser.go │ └── obserser_test.go ├── 14.3_解耦观察者 │ ├── obserser.go │ └── obserser_test.go ├── 14.4_双向解耦 │ ├── obserser.go │ └── obserser_test.go ├── README.md └── 观察者模式(常规实现) │ ├── obserser.go │ └── obserser_test.go ├── 15_抽象工厂模式 ├── 15.2_数据库访问程序 │ ├── abstractfactory.go │ └── abstractfactory_test.go ├── 15.3_工厂方法模式访问数据库 │ ├── abstractfactory.go │ └── abstractfactory_test.go ├── 15.4_抽象工厂方法访问数据库 │ ├── abstractfactory.go │ └── abstractfactory_test.go ├── README.md └── model │ ├── department.go │ └── user.go ├── 16_状态模式 ├── 16.5_状态模式(常规实现) │ ├── state.go │ └── state_test.go ├── 16.7_工作状态-状态模式 │ ├── state.go │ └── state_test.go └── README.md ├── 17_适配器模式 ├── 17.2_适配器模式(常规实现) │ ├── adapter.go │ └── adapter_test.go ├── 17.4_篮球翻译适配器 │ ├── adapter.go │ └── adapter_test.go └── README.md ├── 18_备忘录模式 ├── 18.2_游戏存进度 │ ├── memento.go │ └── memento_test.go ├── 18.4_备忘录模式(常规实现) │ ├── memento.go │ └── memento_test.go ├── 18.5_游戏进度备忘 │ ├── memento.go │ └── memento_test.go └── README.md ├── 19_组合模式 ├── 19.2_组合模式(常规实现) │ ├── composite.go │ └── composite_test.go ├── 19.5_公司管理系统 │ ├── composite.go │ └── composite_test.go └── README.md ├── 20_迭代器模式 ├── README.md ├── iterator.go └── iterator_test.go ├── 21_单例模式 ├── README.md ├── singleton.go └── singleton_test.go ├── 22_桥接模式 ├── 22.3_合成、聚合复用原则 │ └── README.md ├── 22.4_松耦合程序 │ ├── bridge.go │ └── bridge_test.go ├── 22.6_桥接模式(常规实现) │ ├── bridge.go │ └── bridge_test.go └── README.md ├── 23_命令模式 ├── 23.4_松耦合设计 │ ├── command.go │ └── command_test.go ├── 23.5_松耦合后 │ ├── command.go │ └── command_test.go ├── 23.6_命令模式(常规实现) │ ├── command.go │ └── command_test.go └── README.md ├── 24_职责链模式 ├── 24.3_职责链模式(常规实现) │ ├── chain_of_responsibility.go │ └── chain_of_responsibility_test.go └── README.md ├── 25_中介者模式 ├── 25.2_中介者模式(常规实现) │ ├── mediator.go │ └── mediator_test.go ├── 25.3_安理会做中介 │ ├── mediator.go │ └── mediator_test.go └── README.md ├── 26_享元模式 ├── 26.2_享元模式常规实现 │ ├── flyweight.go │ └── flyweight_test.go ├── 26.3_网站共享代码 │ ├── flyweight.go │ └── flyweight_test.go └── README.md ├── 27_解析器模式 ├── 27.2_解析器模式(常规实现) │ ├── interpreter.go │ └── interpreter_test.go └── README.md ├── 28_访问者模式 ├── 28.3_简单的面向对象设计 │ ├── visitor.go │ └── visitor_test.go ├── 28.4_用模式实现 │ ├── visitor.go │ └── visitor_test.go ├── 28.6_访问者模式(常规实现) │ ├── visitor.go │ └── visitor_test.go └── README.md ├── LICENSE ├── README.md └── go.mod /01_简单工厂模式/1.10_简单工厂模式/simplefactory.go: -------------------------------------------------------------------------------- 1 | package simplefactory 2 | 3 | import "log" 4 | 5 | //Operation 运算结构体 6 | type Operation interface { 7 | GetResult(numberA, numberB float64) float64 8 | } 9 | 10 | //NewOperation 返回运算示例 11 | func NewOperation(operate string) Operation { 12 | var oper Operation 13 | switch operate { 14 | case "+": 15 | oper = new(OperationAdd) 16 | break 17 | case "-": 18 | oper = new(OperationSub) 19 | break 20 | case "*": 21 | oper = new(OperationMul) 22 | break 23 | case "/": 24 | oper = new(OperationDiv) 25 | break 26 | } 27 | return oper 28 | } 29 | 30 | //OperationAdd 加法运算 31 | type OperationAdd struct { 32 | } 33 | 34 | //GetResult 获取加法结果 35 | func (*OperationAdd) GetResult(numberA, numberB float64) float64 { 36 | return numberA + numberB 37 | } 38 | 39 | //OperationSub 减法运算 40 | type OperationSub struct { 41 | } 42 | 43 | //GetResult 获取减法结果 44 | func (*OperationSub) GetResult(numberA, numberB float64) float64 { 45 | return numberA - numberB 46 | } 47 | 48 | //OperationMul 乘法运算 49 | type OperationMul struct { 50 | } 51 | 52 | //GetResult 获取乘法结果 53 | func (*OperationMul) GetResult(numberA, numberB float64) float64 { 54 | return numberA * numberB 55 | } 56 | 57 | //OperationDiv 除法运算 58 | type OperationDiv struct { 59 | } 60 | 61 | //GetResult 获取除法结果 62 | func (*OperationDiv) GetResult(numberA, numberB float64) float64 { 63 | if numberB == 0 { 64 | log.Fatal("除数不能为0") 65 | } 66 | return numberA / numberB 67 | } 68 | -------------------------------------------------------------------------------- /01_简单工厂模式/1.10_简单工厂模式/simplefactory_test.go: -------------------------------------------------------------------------------- 1 | package simplefactory 2 | 3 | import "testing" 4 | 5 | func TestOperator(t *testing.T) { 6 | oper := NewOperation("+") 7 | strResult := oper.GetResult(1, 2) 8 | if strResult != 3 { 9 | t.Fatal("TestOperator test fail") 10 | } 11 | oper = NewOperation("*") 12 | strResult = oper.GetResult(2, 2) 13 | if strResult != 4 { 14 | t.Fatal("TestOperator test fail") 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /01_简单工厂模式/1.8_业务封装/simplefactory.go: -------------------------------------------------------------------------------- 1 | package simplefactory 2 | 3 | //Operation 运算结构体 4 | type Operation struct { 5 | } 6 | 7 | //GetResult 获取运算结果 8 | func (*Operation) GetResult(numberA, numberB float64, operate string) float64 { 9 | var result float64 = 0 10 | switch operate { 11 | case "+": 12 | result = numberA + numberB 13 | break 14 | case "-": 15 | result = numberA - numberB 16 | break 17 | case "*": 18 | result = numberA * numberB 19 | break 20 | case "/": 21 | result = numberA / numberB 22 | break 23 | } 24 | return result 25 | } 26 | -------------------------------------------------------------------------------- /01_简单工厂模式/1.8_业务封装/simplefactory_test.go: -------------------------------------------------------------------------------- 1 | package simplefactory 2 | 3 | import "testing" 4 | 5 | func TestOperator(t *testing.T) { 6 | oper := new(Operation) 7 | strResult := oper.GetResult(1, 2, "+") 8 | if strResult != 3 { 9 | t.Fatal("TestOperator test fail") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /01_简单工厂模式/README.md: -------------------------------------------------------------------------------- 1 | ### 简单工厂模式(Simple Factory Pattern) 2 | 3 | 可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。 -------------------------------------------------------------------------------- /02_策略模式/2.3_简单工厂实现/strategy.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | //CashSuper 现金收费接口 4 | type CashSuper interface { 5 | AcceptCash(money float64) float64 6 | } 7 | 8 | //CashNormal 正常收费 9 | type CashNormal struct { 10 | } 11 | 12 | //AcceptCash 正常收费,原价返回 13 | func (*CashNormal) AcceptCash(money float64) float64 { 14 | return money 15 | } 16 | 17 | //CashRebate 打折收费 18 | type CashRebate struct { 19 | moneyRebate float64 20 | } 21 | 22 | //NewCashRebate 构造函数,返回CashRebate 23 | func NewCashRebate(moneyRebate float64) CashSuper { 24 | return &CashRebate{ 25 | moneyRebate: moneyRebate, 26 | } 27 | } 28 | 29 | //AcceptCash 打折收费,乘以折扣 30 | func (rebate *CashRebate) AcceptCash(money float64) float64 { 31 | return money * rebate.moneyRebate 32 | } 33 | 34 | //CashReturn 返利收费 35 | type CashReturn struct { 36 | moneyCondition, moneyReturn float64 37 | } 38 | 39 | //NewCashReturn 构造函数,返回CashReturn 40 | func NewCashReturn(moneyCondition, moneyReturn float64) CashSuper { 41 | return &CashReturn{ 42 | moneyCondition: moneyCondition, 43 | moneyReturn: moneyReturn, 44 | } 45 | } 46 | 47 | //AcceptCash 返利收费 48 | func (re *CashReturn) AcceptCash(money float64) float64 { 49 | if money >= re.moneyCondition { 50 | money -= re.moneyReturn 51 | } 52 | return money 53 | } 54 | 55 | //CashFactory 现金收费工厂结构体 56 | type CashFactory struct { 57 | } 58 | 59 | //CreateCashAccept 返回现金收取方式实例 60 | func (*CashFactory) CreateCashAccept(strType string) CashSuper { 61 | var cs CashSuper 62 | switch strType { 63 | case "正常收费": 64 | cs = &CashNormal{} 65 | break 66 | case "满300返100": 67 | cs = NewCashReturn(300, 100) 68 | break 69 | case "打八折": 70 | cs = NewCashRebate(0.8) 71 | break 72 | } 73 | return cs 74 | } 75 | -------------------------------------------------------------------------------- /02_策略模式/2.3_简单工厂实现/strategy_test.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | import "testing" 4 | 5 | func TestStrategy(t *testing.T) { 6 | factory := new(CashFactory) 7 | var cs CashSuper 8 | cs = factory.CreateCashAccept("正常收费") 9 | res := cs.AcceptCash(300) 10 | if res != 300 { 11 | t.Fatal("CashNormal test fail") 12 | } 13 | cs = factory.CreateCashAccept("打八折") 14 | res = cs.AcceptCash(300) 15 | if res != 240 { 16 | t.Fatal("CashRebate test fail") 17 | } 18 | cs = factory.CreateCashAccept("满300返100") 19 | res = cs.AcceptCash(300) 20 | if res != 200 { 21 | t.Fatal("CashReturn test fail") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /02_策略模式/2.4_策略模式(常规实现)/strategy.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | import "fmt" 4 | 5 | //Strategy 抽象算法类 6 | type Strategy interface { 7 | AlgorithmInterface() 8 | } 9 | 10 | //ConcreteStrategyA 具体算法A 11 | type ConcreteStrategyA struct { 12 | } 13 | 14 | //AlgorithmInterface 实现算法A 15 | func (*ConcreteStrategyA) AlgorithmInterface() { 16 | fmt.Println("算法A实现") 17 | } 18 | 19 | //ConcreteStrategyB 具体算法B 20 | type ConcreteStrategyB struct { 21 | } 22 | 23 | //AlgorithmInterface 实现算法B 24 | func (*ConcreteStrategyB) AlgorithmInterface() { 25 | fmt.Println("算法B实现") 26 | } 27 | 28 | //ConcreteStrategyC 具体算法C 29 | type ConcreteStrategyC struct { 30 | } 31 | 32 | //AlgorithmInterface 实现算法C 33 | func (*ConcreteStrategyC) AlgorithmInterface() { 34 | fmt.Println("算法C实现") 35 | } 36 | 37 | //Context 上下文 38 | type Context struct { 39 | strategy Strategy 40 | } 41 | 42 | //NewContext 上下文构造函数 43 | func NewContext(strategy Strategy) *Context { 44 | return &Context{ 45 | strategy: strategy, 46 | } 47 | } 48 | 49 | //ContextInterface 上下文接口 50 | func (context *Context) ContextInterface() { 51 | context.strategy.AlgorithmInterface() 52 | } 53 | -------------------------------------------------------------------------------- /02_策略模式/2.4_策略模式(常规实现)/strategy_test.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | func ExampleStrategy() { 4 | var context *Context 5 | context = NewContext(new(ConcreteStrategyA)) 6 | context.ContextInterface() 7 | context = NewContext(new(ConcreteStrategyB)) 8 | context.ContextInterface() 9 | context = NewContext(new(ConcreteStrategyC)) 10 | context.ContextInterface() 11 | // Output: 12 | // 算法A实现 13 | // 算法B实现 14 | // 算法C实现 15 | } 16 | -------------------------------------------------------------------------------- /02_策略模式/2.5_策略模式实现/strategy.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | //CashSuper 现金收费接口 4 | type CashSuper interface { 5 | AcceptCash(money float64) float64 6 | } 7 | 8 | //CashNormal 正常收费 9 | type CashNormal struct { 10 | } 11 | 12 | //AcceptCash 正常收费,原价返回 13 | func (*CashNormal) AcceptCash(money float64) float64 { 14 | return money 15 | } 16 | 17 | //CashRebate 打折收费 18 | type CashRebate struct { 19 | moneyRebate float64 20 | } 21 | 22 | //NewCashRebate 构造函数,返回CashRebate 23 | func NewCashRebate(moneyRebate float64) CashSuper { 24 | return &CashRebate{ 25 | moneyRebate: moneyRebate, 26 | } 27 | } 28 | 29 | //AcceptCash 打折收费,乘以折扣 30 | func (rebate *CashRebate) AcceptCash(money float64) float64 { 31 | return money * rebate.moneyRebate 32 | } 33 | 34 | //CashReturn 返利收费 35 | type CashReturn struct { 36 | moneyCondition, moneyReturn float64 37 | } 38 | 39 | //NewCashReturn 构造函数,返回CashReturn 40 | func NewCashReturn(moneyCondition, moneyReturn float64) CashSuper { 41 | return &CashReturn{ 42 | moneyCondition: moneyCondition, 43 | moneyReturn: moneyReturn, 44 | } 45 | } 46 | 47 | //AcceptCash 返利收费 48 | func (re *CashReturn) AcceptCash(money float64) float64 { 49 | if money >= re.moneyCondition { 50 | money -= re.moneyReturn 51 | } 52 | return money 53 | } 54 | 55 | //CashContext 收费策略 56 | type CashContext struct { 57 | cs CashSuper 58 | } 59 | 60 | //NewCashContext CashContext构造函数 61 | func NewCashContext(cs CashSuper) *CashContext { 62 | return &CashContext{ 63 | cs: cs, 64 | } 65 | } 66 | 67 | //GetResult 得到现金促销计算结果(不同的策略行为导致不同的结果) 68 | func (context *CashContext) GetResult(money float64) float64 { 69 | return context.cs.AcceptCash(money) 70 | } 71 | -------------------------------------------------------------------------------- /02_策略模式/2.5_策略模式实现/strategy_test.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | import "testing" 4 | 5 | func TestStrategy(t *testing.T) { 6 | var cc *CashContext 7 | strType := "打八折" 8 | switch strType { 9 | case "正常收费": 10 | cc = NewCashContext(new(CashNormal)) 11 | break 12 | case "满300返100": 13 | cc = NewCashContext(NewCashReturn(300, 100)) 14 | break 15 | case "打八折": 16 | cc = NewCashContext(NewCashRebate(0.8)) 17 | break 18 | } 19 | res := cc.GetResult(300) 20 | if res != 240 { 21 | t.Fatal("CashRebate test fail") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /02_策略模式/2.6_策略和简单工厂结合/strategy.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | //CashSuper 现金收费接口 4 | type CashSuper interface { 5 | AcceptCash(money float64) float64 6 | } 7 | 8 | //CashNormal 正常收费 9 | type CashNormal struct { 10 | } 11 | 12 | //AcceptCash 正常收费,原价返回 13 | func (*CashNormal) AcceptCash(money float64) float64 { 14 | return money 15 | } 16 | 17 | //CashRebate 打折收费 18 | type CashRebate struct { 19 | moneyRebate float64 20 | } 21 | 22 | //NewCashRebate 构造函数,返回CashRebate 23 | func NewCashRebate(moneyRebate float64) CashSuper { 24 | return &CashRebate{ 25 | moneyRebate: moneyRebate, 26 | } 27 | } 28 | 29 | //AcceptCash 打折收费,乘以折扣 30 | func (rebate *CashRebate) AcceptCash(money float64) float64 { 31 | return money * rebate.moneyRebate 32 | } 33 | 34 | //CashReturn 返利收费 35 | type CashReturn struct { 36 | moneyCondition, moneyReturn float64 37 | } 38 | 39 | //NewCashReturn 构造函数,返回CashReturn 40 | func NewCashReturn(moneyCondition, moneyReturn float64) CashSuper { 41 | return &CashReturn{ 42 | moneyCondition: moneyCondition, 43 | moneyReturn: moneyReturn, 44 | } 45 | } 46 | 47 | //AcceptCash 返利收费 48 | func (re *CashReturn) AcceptCash(money float64) float64 { 49 | if money >= re.moneyCondition { 50 | money -= re.moneyReturn 51 | } 52 | return money 53 | } 54 | 55 | //CashContext 收费策略 56 | type CashContext struct { 57 | cs CashSuper 58 | } 59 | 60 | //NewCashContext CashContext构造函数 61 | func NewCashContext(strType string) *CashContext { 62 | var cs CashSuper 63 | switch strType { 64 | case "正常收费": 65 | cs = new(CashNormal) 66 | break 67 | case "满300返100": 68 | cs = NewCashReturn(300, 100) 69 | break 70 | case "打八折": 71 | cs = NewCashRebate(0.8) 72 | break 73 | } 74 | return &CashContext{ 75 | cs: cs, 76 | } 77 | } 78 | 79 | //GetResult 得到现金促销计算结果(不同的策略行为导致不同的结果) 80 | func (context *CashContext) GetResult(money float64) float64 { 81 | return context.cs.AcceptCash(money) 82 | } 83 | -------------------------------------------------------------------------------- /02_策略模式/2.6_策略和简单工厂结合/strategy_test.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | import "testing" 4 | 5 | func TestStrategy(t *testing.T) { 6 | var cc *CashContext 7 | cc = NewCashContext("正常收费") 8 | res := cc.GetResult(300) 9 | if res != 300 { 10 | t.Fatal("CashNormal test fail") 11 | } 12 | cc = NewCashContext("打八折") 13 | res = cc.GetResult(300) 14 | if res != 240 { 15 | t.Fatal("CashRebate test fail") 16 | } 17 | cc = NewCashContext("满300返100") 18 | res = cc.GetResult(300) 19 | if res != 200 { 20 | t.Fatal("CashReturn test fail") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /02_策略模式/README.md: -------------------------------------------------------------------------------- 1 | ### 策略模式(Strategy Pattern) 2 | 3 | 定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。 -------------------------------------------------------------------------------- /03_单一职责原则/README.md: -------------------------------------------------------------------------------- 1 | ### 单一职责原则(Single responsibility principle) 2 | 它规定一个类应该只有一个发生变化的原因。 3 | 4 | 5 | 所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。 6 | 7 | 8 | 如果一个类承担的职责过多,就等于把这些职责耦合在一起了。一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当发生变化时,设计会遭受到意想不到的破坏。而如果想要避免这种现象的发生,就要尽可能的遵守单一职责原则。此原则的核心就是解耦和增强内聚性。 -------------------------------------------------------------------------------- /04_开放封闭原则/README.md: -------------------------------------------------------------------------------- 1 | ### 开放封闭原则(Open Closed Principle) 2 | 3 | 定义:软件实体(类、模块、函数)等应该是可以扩展的,但是不可修改。 4 | 5 | 思想:当需要改变一个程序的功能或者给这个程序增加新功能的时候,可以使用增加代码的方式,但是不允许 改动程序的源代码。 -------------------------------------------------------------------------------- /05_依赖倒转原则/README.md: -------------------------------------------------------------------------------- 1 | ### 依赖倒转原则(Dependence Inversion Principle) 2 | 3 | A.高层模块不应该依赖底层模块,两个都应该依赖抽象 4 | 5 | B.抽象不应该依赖细节,细节应该依赖抽象 -------------------------------------------------------------------------------- /06_装饰模式/6.1_穿衣01/decorator.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | import "fmt" 4 | 5 | //Person 人 6 | type Person struct { 7 | name string 8 | } 9 | 10 | //NewPerson Person构造函数 11 | func NewPerson(name string) *Person { 12 | return &Person{ 13 | name: name, 14 | } 15 | } 16 | 17 | //WearTShirts 大T恤 18 | func (*Person) WearTShirts() { 19 | fmt.Print("大T恤 ") 20 | } 21 | 22 | //WearBigTrouser 垮裤 23 | func (*Person) WearBigTrouser() { 24 | fmt.Print("垮裤 ") 25 | } 26 | 27 | //WearSneakers 破球鞋 28 | func (*Person) WearSneakers() { 29 | fmt.Print("破球鞋 ") 30 | } 31 | 32 | //WearSuit 西装 33 | func (*Person) WearSuit() { 34 | fmt.Print("西装 ") 35 | } 36 | 37 | //WearTie 领带 38 | func (*Person) WearTie() { 39 | fmt.Print("领带 ") 40 | } 41 | 42 | //WearLeatherShoes 皮鞋 43 | func (*Person) WearLeatherShoes() { 44 | fmt.Print("皮鞋 ") 45 | } 46 | 47 | //Show 显示人名 48 | func (person *Person) Show() { 49 | fmt.Printf("装扮的%s\n", person.name) 50 | } 51 | -------------------------------------------------------------------------------- /06_装饰模式/6.1_穿衣01/decorator_test.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | import "fmt" 4 | 5 | func ExampleDecorator() { 6 | xc := NewPerson("小菜") 7 | fmt.Println("\n第一种装扮:") 8 | xc.WearTShirts() 9 | xc.WearBigTrouser() 10 | xc.WearSneakers() 11 | xc.Show() 12 | 13 | fmt.Println("\n第二种装扮:") 14 | xc.WearSuit() 15 | xc.WearTie() 16 | xc.WearLeatherShoes() 17 | xc.Show() 18 | // Output: 19 | // 第一种装扮: 20 | // 大T恤 垮裤 破球鞋 装扮的小菜 21 | // 22 | // 第二种装扮: 23 | // 西装 领带 皮鞋 装扮的小菜 24 | } 25 | -------------------------------------------------------------------------------- /06_装饰模式/6.2_穿衣02/decorator.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | import "fmt" 4 | 5 | //Person 人 6 | type Person struct { 7 | name string 8 | } 9 | 10 | //NewPerson Person构造函数 11 | func NewPerson(name string) *Person { 12 | return &Person{ 13 | name: name, 14 | } 15 | } 16 | 17 | //Show 显示人名 18 | func (person *Person) Show() { 19 | fmt.Printf("装扮的%s\n", person.name) 20 | } 21 | 22 | //Finery 服饰 23 | type Finery interface { 24 | Show() 25 | } 26 | 27 | //TShirts 大T恤 28 | type TShirts struct { 29 | } 30 | 31 | //Show 大T恤 32 | func (*TShirts) Show() { 33 | fmt.Print("大T恤 ") 34 | } 35 | 36 | //BigTrouser 垮裤 37 | type BigTrouser struct { 38 | } 39 | 40 | //Show 垮裤 41 | func (*BigTrouser) Show() { 42 | fmt.Print("垮裤 ") 43 | } 44 | 45 | //Sneakers 破球鞋 46 | type Sneakers struct { 47 | } 48 | 49 | //Show 破球鞋 50 | func (*Sneakers) Show() { 51 | fmt.Print("破球鞋 ") 52 | } 53 | 54 | //Suit 西装 55 | type Suit struct { 56 | } 57 | 58 | //Show 西装 59 | func (*Suit) Show() { 60 | fmt.Print("西装 ") 61 | } 62 | 63 | //Tie 领带 64 | type Tie struct { 65 | } 66 | 67 | //Show 领带 68 | func (*Tie) Show() { 69 | fmt.Print("领带 ") 70 | } 71 | 72 | //LeatherShoes 皮鞋 73 | type LeatherShoes struct { 74 | } 75 | 76 | //Show 皮鞋 77 | func (*LeatherShoes) Show() { 78 | fmt.Print("皮鞋 ") 79 | } 80 | -------------------------------------------------------------------------------- /06_装饰模式/6.2_穿衣02/decorator_test.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | import "fmt" 4 | 5 | func ExampleDecorator() { 6 | xc := NewPerson("小菜") 7 | fmt.Println("\n第一种装扮:") 8 | 9 | dtx := new(TShirts) 10 | kk := new(BigTrouser) 11 | pqx := new(Sneakers) 12 | 13 | dtx.Show() 14 | kk.Show() 15 | pqx.Show() 16 | xc.Show() 17 | 18 | fmt.Println("\n第二种装扮:") 19 | 20 | xz := new(Suit) 21 | ld := new(Tie) 22 | px := new(LeatherShoes) 23 | 24 | xz.Show() 25 | ld.Show() 26 | px.Show() 27 | xc.Show() 28 | // Output: 29 | // 第一种装扮: 30 | // 大T恤 垮裤 破球鞋 装扮的小菜 31 | // 32 | // 第二种装扮: 33 | // 西装 领带 皮鞋 装扮的小菜 34 | } 35 | -------------------------------------------------------------------------------- /06_装饰模式/6.3_装饰模式(常规实现)/decorator.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | //Component 部件 8 | type Component interface { 9 | Operation() 10 | } 11 | 12 | //ConcreteComponent 具体部件 13 | type ConcreteComponent struct { 14 | } 15 | 16 | //Operation 具体操作 17 | func (*ConcreteComponent) Operation() { 18 | fmt.Println("具体对象的操作") 19 | } 20 | 21 | //Decorator 装饰器 22 | type Decorator struct { 23 | Component 24 | } 25 | 26 | //Operation 装饰器操作 27 | func (decorator *Decorator) Operation() { 28 | if decorator.Component != nil { 29 | decorator.Component.Operation() 30 | } 31 | } 32 | 33 | //ConcreteDecoratorA 具体装饰对象A 34 | type ConcreteDecoratorA struct { 35 | addedState string 36 | //想要调用父类方法,需要把父类组合到结构体中 37 | Component 38 | } 39 | 40 | //Operation 具体装饰对象A的操作 41 | func (a *ConcreteDecoratorA) Operation() { 42 | a.Component.Operation() 43 | a.addedState = "New State" 44 | fmt.Println("具体装饰对象A的操作") 45 | } 46 | 47 | //ConcreteDecoratorB 具体装饰对象B 48 | type ConcreteDecoratorB struct { 49 | //想要调用父类方法,需要把父类组合到结构体中 50 | Component 51 | } 52 | 53 | //Operation 具体装饰对象B的操作 54 | func (b *ConcreteDecoratorB) Operation() { 55 | b.Component.Operation() 56 | b.AddedBehavior() 57 | fmt.Println("具体装饰对象B的操作") 58 | } 59 | 60 | //AddedBehavior 添加新特性 61 | func (b *ConcreteDecoratorB) AddedBehavior() { 62 | 63 | } 64 | -------------------------------------------------------------------------------- /06_装饰模式/6.3_装饰模式(常规实现)/decorator_test.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | func ExampleDecorator() { 4 | c := new(ConcreteComponent) 5 | d1 := new(ConcreteDecoratorA) 6 | d2 := new(ConcreteDecoratorB) 7 | 8 | d1.Component = c 9 | d2.Component = d1 10 | 11 | d2.Operation() 12 | 13 | // Output: 14 | // 具体对象的操作 15 | // 具体装饰对象A的操作 16 | // 具体装饰对象B的操作 17 | 18 | } 19 | -------------------------------------------------------------------------------- /06_装饰模式/6.4_穿衣03/decorator.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | import "fmt" 4 | 5 | //Person 人 6 | type Person interface { 7 | Show() 8 | } 9 | 10 | //ConcretePerson 具体的人 11 | type ConcretePerson struct { 12 | name string 13 | } 14 | 15 | //NewConcretePerson ConcretePerson构造函数 16 | func NewConcretePerson(name string) *ConcretePerson { 17 | return &ConcretePerson{ 18 | name: name, 19 | } 20 | } 21 | 22 | //Show 显示人名 23 | func (c *ConcretePerson) Show() { 24 | fmt.Printf("装扮的%s\n", c.name) 25 | } 26 | 27 | //Finery 服饰 28 | type Finery struct { 29 | Person 30 | } 31 | 32 | //Decorate 服饰装饰器 33 | func (f *Finery) Decorate(component Person) { 34 | f.Person = component 35 | } 36 | 37 | //Show 服饰展示 38 | func (f *Finery) Show() { 39 | if f.Person != nil { 40 | f.Person.Show() 41 | } 42 | } 43 | 44 | //TShirts 大T恤 45 | type TShirts struct { 46 | Person 47 | } 48 | 49 | //Show 大T恤 50 | func (t *TShirts) Show() { 51 | fmt.Print("大T恤 ") 52 | t.Person.Show() 53 | } 54 | 55 | //BigTrouser 垮裤 56 | type BigTrouser struct { 57 | Person 58 | } 59 | 60 | //Show 垮裤 61 | func (b *BigTrouser) Show() { 62 | fmt.Print("垮裤 ") 63 | b.Person.Show() 64 | } 65 | 66 | //Sneakers 破球鞋 67 | type Sneakers struct { 68 | Person 69 | } 70 | 71 | //Show 破球鞋 72 | func (s *Sneakers) Show() { 73 | fmt.Print("破球鞋 ") 74 | s.Person.Show() 75 | } 76 | 77 | //Suit 西装 78 | type Suit struct { 79 | Person 80 | } 81 | 82 | //Show 西装 83 | func (s *Suit) Show() { 84 | fmt.Print("西装 ") 85 | s.Person.Show() 86 | } 87 | 88 | //Tie 领带 89 | type Tie struct { 90 | Person 91 | } 92 | 93 | //Show 领带 94 | func (t *Tie) Show() { 95 | fmt.Print("领带 ") 96 | t.Person.Show() 97 | } 98 | 99 | //LeatherShoes 皮鞋 100 | type LeatherShoes struct { 101 | Person 102 | } 103 | 104 | //Show 皮鞋 105 | func (f *LeatherShoes) Show() { 106 | fmt.Print("皮鞋 ") 107 | f.Person.Show() 108 | } 109 | -------------------------------------------------------------------------------- /06_装饰模式/6.4_穿衣03/decorator_test.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | import "fmt" 4 | 5 | func ExampleDecorator() { 6 | xc := NewConcretePerson("小菜") 7 | fmt.Println("\n第一种装扮:") 8 | 9 | pqx := new(Sneakers) 10 | kk := new(BigTrouser) 11 | dtx := new(TShirts) 12 | 13 | pqx.Person = xc 14 | kk.Person = pqx 15 | dtx.Person = kk 16 | dtx.Show() 17 | 18 | fmt.Println("\n第二种装扮:") 19 | 20 | px := new(LeatherShoes) 21 | ld := new(Tie) 22 | xz := new(Suit) 23 | 24 | px.Person = xc 25 | ld.Person = px 26 | xz.Person = ld 27 | xz.Show() 28 | 29 | // Output: 30 | // 第一种装扮: 31 | // 大T恤 垮裤 破球鞋 装扮的小菜 32 | // 33 | // 第二种装扮: 34 | // 西装 领带 皮鞋 装扮的小菜 35 | } 36 | -------------------------------------------------------------------------------- /06_装饰模式/README.md: -------------------------------------------------------------------------------- 1 | ### 装饰模式(Decorator Pattern) 2 | 3 | 动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。 -------------------------------------------------------------------------------- /07_代理模式/7.2_没有代理的代码/proxy.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import "fmt" 4 | 5 | //Pursuit 追求者 6 | type Pursuit struct { 7 | mm *SchoolGirl 8 | } 9 | 10 | //GiveDolls 送洋娃娃 11 | func (p *Pursuit) GiveDolls() { 12 | fmt.Printf("%s 送你洋娃娃\n", p.mm.Name) 13 | } 14 | 15 | //GiveFlowers 送鲜花 16 | func (p *Pursuit) GiveFlowers() { 17 | fmt.Printf("%s 送你鲜花\n", p.mm.Name) 18 | } 19 | 20 | //GiveChocolate 送巧克力 21 | func (p *Pursuit) GiveChocolate() { 22 | fmt.Printf("%s 送你巧克力\n", p.mm.Name) 23 | } 24 | 25 | //SchoolGirl 被追求者 26 | type SchoolGirl struct { 27 | Name string 28 | } 29 | -------------------------------------------------------------------------------- /07_代理模式/7.2_没有代理的代码/proxy_test.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | func ExampleProxy() { 4 | jiaojiao := &SchoolGirl{Name: "李娇娇"} 5 | zhuojiayi := &Pursuit{mm: jiaojiao} 6 | zhuojiayi.GiveDolls() 7 | zhuojiayi.GiveFlowers() 8 | zhuojiayi.GiveChocolate() 9 | // Output: 10 | // 李娇娇 送你洋娃娃 11 | // 李娇娇 送你鲜花 12 | // 李娇娇 送你巧克力 13 | } 14 | -------------------------------------------------------------------------------- /07_代理模式/7.3_没有代理的代码/proxy.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import "fmt" 4 | 5 | //Proxy 代理 6 | type Proxy struct { 7 | mm *SchoolGirl 8 | } 9 | 10 | //GiveDolls 送洋娃娃 11 | func (p *Proxy) GiveDolls() { 12 | fmt.Printf("%s 送你洋娃娃\n", p.mm.Name) 13 | } 14 | 15 | //GiveFlowers 送鲜花 16 | func (p *Proxy) GiveFlowers() { 17 | fmt.Printf("%s 送你鲜花\n", p.mm.Name) 18 | } 19 | 20 | //GiveChocolate 送巧克力 21 | func (p *Proxy) GiveChocolate() { 22 | fmt.Printf("%s 送你巧克力\n", p.mm.Name) 23 | } 24 | 25 | //SchoolGirl 被追求者 26 | type SchoolGirl struct { 27 | Name string 28 | } 29 | -------------------------------------------------------------------------------- /07_代理模式/7.3_没有代理的代码/proxy_test.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | func ExampleProxy() { 4 | jiaojiao := &SchoolGirl{Name: "李娇娇"} 5 | daili := &Proxy{mm: jiaojiao} 6 | daili.GiveDolls() 7 | daili.GiveFlowers() 8 | daili.GiveChocolate() 9 | // Output: 10 | // 李娇娇 送你洋娃娃 11 | // 李娇娇 送你鲜花 12 | // 李娇娇 送你巧克力 13 | } 14 | -------------------------------------------------------------------------------- /07_代理模式/7.4_符合实际的代码/proxy.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import "fmt" 4 | 5 | //GiveGift 送礼物 6 | type GiveGift interface { 7 | GiveDolls() 8 | GiveFlowers() 9 | GiveChocolate() 10 | } 11 | 12 | //Pursuit 追求者 13 | type Pursuit struct { 14 | mm *SchoolGirl 15 | } 16 | 17 | //GiveDolls 送洋娃娃 18 | func (p *Pursuit) GiveDolls() { 19 | fmt.Printf("%s 送你洋娃娃\n", p.mm.Name) 20 | } 21 | 22 | //GiveFlowers 送鲜花 23 | func (p *Pursuit) GiveFlowers() { 24 | fmt.Printf("%s 送你鲜花\n", p.mm.Name) 25 | } 26 | 27 | //GiveChocolate 送巧克力 28 | func (p *Pursuit) GiveChocolate() { 29 | fmt.Printf("%s 送你巧克力\n", p.mm.Name) 30 | } 31 | 32 | //Proxy 追求者 33 | type Proxy struct { 34 | gg *Pursuit 35 | } 36 | 37 | //GiveDolls 送洋娃娃 38 | func (p *Proxy) GiveDolls() { 39 | p.gg.GiveDolls() 40 | } 41 | 42 | //GiveFlowers 送鲜花 43 | func (p *Proxy) GiveFlowers() { 44 | p.gg.GiveFlowers() 45 | } 46 | 47 | //GiveChocolate 送巧克力 48 | func (p *Proxy) GiveChocolate() { 49 | p.gg.GiveChocolate() 50 | } 51 | 52 | //SchoolGirl 被追求者 53 | type SchoolGirl struct { 54 | Name string 55 | } 56 | -------------------------------------------------------------------------------- /07_代理模式/7.4_符合实际的代码/proxy_test.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | func ExampleProxy() { 4 | jiaojiao := &SchoolGirl{Name: "李娇娇"} 5 | zhuojiayi := &Pursuit{mm: jiaojiao} 6 | daili := &Proxy{gg: zhuojiayi} 7 | daili.GiveDolls() 8 | daili.GiveFlowers() 9 | daili.GiveChocolate() 10 | // Output: 11 | // 李娇娇 送你洋娃娃 12 | // 李娇娇 送你鲜花 13 | // 李娇娇 送你巧克力 14 | } 15 | -------------------------------------------------------------------------------- /07_代理模式/7.5_代理模式(常规实现)/proxy.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import "fmt" 4 | 5 | //Subject 接口 6 | type Subject interface { 7 | Request() 8 | } 9 | 10 | //RealSubject 真实的请求 11 | type RealSubject struct { 12 | } 13 | 14 | //Request 请求 15 | func (*RealSubject) Request() { 16 | fmt.Println("真实的请求") 17 | } 18 | 19 | //Proxy 代理 20 | type Proxy struct { 21 | realSubject *RealSubject 22 | } 23 | 24 | //Request 代理请求 25 | func (p *Proxy) Request() { 26 | if p.realSubject == nil { 27 | p.realSubject = new(RealSubject) 28 | } 29 | p.realSubject.Request() 30 | } 31 | -------------------------------------------------------------------------------- /07_代理模式/7.5_代理模式(常规实现)/proxy_test.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | func ExampleProxy() { 4 | proxy := new(Proxy) 5 | proxy.Request() 6 | // OutPut: 7 | // 真实的请求 8 | } 9 | -------------------------------------------------------------------------------- /07_代理模式/README.md: -------------------------------------------------------------------------------- 1 | ### 代理模式(Proxy Pattern) 2 | 3 | 给某一个对象提供一个代 理,并由代理对象控制对原对象的引用。 -------------------------------------------------------------------------------- /08_工厂方法/8.3_工厂模式实现/factorymethod.go: -------------------------------------------------------------------------------- 1 | package factorymethod 2 | 3 | import "log" 4 | 5 | //Operation 运算结构体 6 | type Operation interface { 7 | GetResult(numberA, numberB float64) float64 8 | } 9 | 10 | //OperationAdd 加法运算 11 | type OperationAdd struct { 12 | } 13 | 14 | //GetResult 获取加法结果 15 | func (*OperationAdd) GetResult(numberA, numberB float64) float64 { 16 | return numberA + numberB 17 | } 18 | 19 | //OperationSub 减法运算 20 | type OperationSub struct { 21 | } 22 | 23 | //GetResult 获取减法结果 24 | func (*OperationSub) GetResult(numberA, numberB float64) float64 { 25 | return numberA - numberB 26 | } 27 | 28 | //OperationMul 乘法运算 29 | type OperationMul struct { 30 | } 31 | 32 | //GetResult 获取乘法结果 33 | func (*OperationMul) GetResult(numberA, numberB float64) float64 { 34 | return numberA * numberB 35 | } 36 | 37 | //OperationDiv 除法运算 38 | type OperationDiv struct { 39 | } 40 | 41 | //GetResult 获取除法结果 42 | func (*OperationDiv) GetResult(numberA, numberB float64) float64 { 43 | if numberB == 0 { 44 | log.Fatal("除数不能为0") 45 | } 46 | return numberA / numberB 47 | } 48 | 49 | //IFactory 工厂方法 50 | type IFactory interface { 51 | CreateOperation() 52 | } 53 | 54 | //AddFactory 专门负责生产“+”的工厂 55 | type AddFactory struct { 56 | } 57 | 58 | //CreateOperation 创建+法实例 59 | func (*AddFactory) CreateOperation() Operation { 60 | return new(OperationAdd) 61 | } 62 | 63 | //SubFactory 专门负责生产“-”的工厂 64 | type SubFactory struct { 65 | } 66 | 67 | //CreateOperation 创建-法实例 68 | func (*SubFactory) CreateOperation() Operation { 69 | return new(OperationSub) 70 | } 71 | 72 | //MulFactory 专门负责生产“*”的工厂 73 | type MulFactory struct { 74 | } 75 | 76 | //CreateOperation 创建*法实例 77 | func (*MulFactory) CreateOperation() Operation { 78 | return new(OperationMul) 79 | } 80 | 81 | //DivFactory 专门负责生产“/”的工厂 82 | type DivFactory struct { 83 | } 84 | 85 | //CreateOperation 创建*法实例 86 | func (*DivFactory) CreateOperation() Operation { 87 | return new(OperationDiv) 88 | } 89 | -------------------------------------------------------------------------------- /08_工厂方法/8.3_工厂模式实现/factorymethod_test.go: -------------------------------------------------------------------------------- 1 | package factorymethod 2 | 3 | import "testing" 4 | 5 | func TestFactorymethoda(t *testing.T) { 6 | operFactory := new(AddFactory) 7 | oper := operFactory.CreateOperation() 8 | res := oper.GetResult(1, 2) 9 | if res != 3 { 10 | t.Fatal("AddFactory test fail") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /08_工厂方法/8.5_雷锋工厂/factorymethod.go: -------------------------------------------------------------------------------- 1 | package factorymethod 2 | 3 | import "fmt" 4 | 5 | //ILeiFeng 雷锋接口 6 | type ILeiFeng interface { 7 | Sweep() 8 | Wash() 9 | BuyRice() 10 | } 11 | 12 | //LeiFeng 雷锋 13 | type LeiFeng struct { 14 | } 15 | 16 | //Sweep 扫地 17 | func (*LeiFeng) Sweep() { 18 | fmt.Println("扫地") 19 | } 20 | 21 | //Wash 洗衣 22 | func (*LeiFeng) Wash() { 23 | fmt.Println("洗衣") 24 | } 25 | 26 | //BuyRice 买米 27 | func (*LeiFeng) BuyRice() { 28 | fmt.Println("买米") 29 | } 30 | 31 | //Undergraduate 学雷锋的大学生 32 | type Undergraduate struct { 33 | } 34 | 35 | //Sweep 扫地 36 | func (*Undergraduate) Sweep() { 37 | fmt.Println("扫地") 38 | } 39 | 40 | //Wash 洗衣 41 | func (*Undergraduate) Wash() { 42 | fmt.Println("洗衣") 43 | } 44 | 45 | //BuyRice 买米 46 | func (*Undergraduate) BuyRice() { 47 | fmt.Println("买米") 48 | } 49 | 50 | //Volunteer 社区志愿者 51 | type Volunteer struct { 52 | } 53 | 54 | //Sweep 扫地 55 | func (*Volunteer) Sweep() { 56 | fmt.Println("扫地") 57 | } 58 | 59 | //Wash 洗衣 60 | func (*Volunteer) Wash() { 61 | fmt.Println("洗衣") 62 | } 63 | 64 | //BuyRice 买米 65 | func (*Volunteer) BuyRice() { 66 | fmt.Println("买米") 67 | } 68 | 69 | //SimpleFactory 简单雷锋工厂 70 | type SimpleFactory struct { 71 | } 72 | 73 | //CreateLeiFeng 新建实例 74 | func (*SimpleFactory) CreateLeiFeng(strType string) ILeiFeng { 75 | var result ILeiFeng 76 | switch strType { 77 | case "学雷锋的大学生": 78 | result = &Undergraduate{} 79 | break 80 | case "社区志愿者": 81 | result = &Volunteer{} 82 | break 83 | } 84 | return result 85 | } 86 | 87 | //IFactory 雷锋工厂 88 | type IFactory interface { 89 | CreateLeiFeng() ILeiFeng 90 | } 91 | 92 | //UndergraduateFactory 学雷锋的大学生工厂 93 | type UndergraduateFactory struct { 94 | } 95 | 96 | //CreateLeiFeng 新建学雷锋的大学生工厂实例 97 | func (*UndergraduateFactory) CreateLeiFeng() ILeiFeng { 98 | return &Undergraduate{} 99 | } 100 | 101 | //VolunteerFactory 社区志愿者工厂 102 | type VolunteerFactory struct { 103 | } 104 | 105 | //CreateLeiFeng 新建社区志愿者工厂实例 106 | func (*VolunteerFactory) CreateLeiFeng() ILeiFeng { 107 | return &Volunteer{} 108 | } 109 | -------------------------------------------------------------------------------- /08_工厂方法/8.5_雷锋工厂/factorymethod_test.go: -------------------------------------------------------------------------------- 1 | package factorymethod 2 | 3 | func ExampleFactorymethod() { 4 | //简单工厂实现 5 | simpleFactory := &SimpleFactory{} 6 | studentA := simpleFactory.CreateLeiFeng("学雷锋的大学生") 7 | studentA.BuyRice() 8 | studentB := simpleFactory.CreateLeiFeng("学雷锋的大学生") 9 | studentB.Sweep() 10 | studentC := simpleFactory.CreateLeiFeng("学雷锋的大学生") 11 | studentC.Wash() 12 | // OutPut: 13 | // 买米 14 | // 扫地 15 | // 洗衣 16 | 17 | //工厂方法实现 18 | factory := &UndergraduateFactory{} 19 | student := factory.CreateLeiFeng() 20 | student.BuyRice() 21 | student.Sweep() 22 | student.Wash() 23 | // 买米 24 | // 扫地 25 | // 洗衣 26 | } 27 | -------------------------------------------------------------------------------- /08_工厂方法/README.md: -------------------------------------------------------------------------------- 1 | ### 工厂方法模式(Factory Method Pattern) 2 | 3 | 在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。 -------------------------------------------------------------------------------- /09_原型模式/9.2_简历初步代码/prototype.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | import "fmt" 4 | 5 | //Resume 简历 6 | type Resume struct { 7 | name string 8 | sex string 9 | age string 10 | timeArea string 11 | company string 12 | } 13 | 14 | //SetPersonalInfo 设置个人信息 15 | func (r *Resume) SetPersonalInfo(sex, age string) { 16 | r.sex = sex 17 | r.age = age 18 | } 19 | 20 | //SetWorkExperience 设置工作经历 21 | func (r *Resume) SetWorkExperience(timeArea, company string) { 22 | r.timeArea = timeArea 23 | r.company = company 24 | } 25 | 26 | //Display 显示 27 | func (r *Resume) Display() { 28 | fmt.Printf("%s %s %s\n", r.name, r.sex, r.age) 29 | fmt.Printf("工作经历:%s %s\n", r.timeArea, r.company) 30 | } 31 | -------------------------------------------------------------------------------- /09_原型模式/9.2_简历初步代码/prototype_test.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | func ExamplePrototype() { 4 | a := &Resume{name: "大鸟"} 5 | a.SetPersonalInfo("男", "29") 6 | a.SetWorkExperience("1998-2000", "XX公司") 7 | 8 | b := a 9 | c := a 10 | 11 | a.Display() 12 | b.Display() 13 | c.Display() 14 | // OutPut: 15 | // 大鸟 男 29 16 | // 工作经历:1998-2000 XX公司 17 | // 大鸟 男 29 18 | // 工作经历:1998-2000 XX公司 19 | // 大鸟 男 29 20 | // 工作经历:1998-2000 XX公司 21 | } 22 | -------------------------------------------------------------------------------- /09_原型模式/9.3_原型模式(常规代码)/prototype.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | //Prototype 原型 4 | type Prototype interface { 5 | Clone() Prototype 6 | } 7 | 8 | //ConcretePrototype 具体对象 9 | type ConcretePrototype struct { 10 | pMap map[string]Prototype 11 | } 12 | 13 | //NewConcretePrototype ConcretePrototype构造函数 14 | func NewConcretePrototype() *ConcretePrototype { 15 | return &ConcretePrototype{ 16 | pMap: make(map[string]Prototype), 17 | } 18 | } 19 | 20 | //Get 获取对象 21 | func (c *ConcretePrototype) Get(id string) Prototype { 22 | return c.pMap[id] 23 | } 24 | 25 | //Set 设置对象 26 | func (c *ConcretePrototype) Set(id string, cloneable Prototype) { 27 | c.pMap[id] = cloneable 28 | } 29 | -------------------------------------------------------------------------------- /09_原型模式/9.3_原型模式(常规代码)/prototype_test.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | import "testing" 4 | 5 | var manager *ConcretePrototype 6 | 7 | type Type1 struct { 8 | name string 9 | } 10 | 11 | func (t *Type1) Clone() Prototype { 12 | tc := *t 13 | return &tc 14 | } 15 | 16 | type Type2 struct { 17 | name string 18 | } 19 | 20 | func (t *Type2) Clone() Prototype { 21 | tc := *t 22 | return &tc 23 | } 24 | 25 | func TestClone(t *testing.T) { 26 | t1 := manager.Get("t1") 27 | 28 | t2 := t1.Clone() 29 | if t1 == t2 { 30 | t.Fatal("error! get clone not working") 31 | } 32 | } 33 | 34 | func TestCloneFromManager(t *testing.T) { 35 | c := manager.Get("t1").Clone() 36 | 37 | t1 := c.(*Type1) 38 | if t1.name != "type1" { 39 | t.Fatal("error") 40 | } 41 | } 42 | 43 | func init() { 44 | manager = NewConcretePrototype() 45 | 46 | t1 := &Type1{ 47 | name: "type1", 48 | } 49 | manager.Set("t1", t1) 50 | } 51 | -------------------------------------------------------------------------------- /09_原型模式/9.4_简历的原型实现/prototype.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | //Prototype 原型 4 | type Prototype interface { 5 | Clone() Prototype 6 | } 7 | 8 | //ConcretePrototype 具体对象 9 | type ConcretePrototype struct { 10 | pMap map[string]Prototype 11 | } 12 | 13 | //NewConcretePrototype ConcretePrototype构造函数 14 | func NewConcretePrototype() *ConcretePrototype { 15 | return &ConcretePrototype{ 16 | pMap: make(map[string]Prototype), 17 | } 18 | } 19 | 20 | //Get 获取对象 21 | func (c *ConcretePrototype) Get(id string) Prototype { 22 | return c.pMap[id] 23 | } 24 | 25 | //Set 设置对象 26 | func (c *ConcretePrototype) Set(id string, cloneable Prototype) { 27 | c.pMap[id] = cloneable 28 | } 29 | -------------------------------------------------------------------------------- /09_原型模式/9.4_简历的原型实现/prototype_test.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var manager *ConcretePrototype 8 | 9 | //Resume 简历 10 | type Resume struct { 11 | name string 12 | sex string 13 | age string 14 | timeArea string 15 | company string 16 | } 17 | 18 | //SetPersonalInfo 设置个人信息 19 | func (r *Resume) SetPersonalInfo(sex, age string) { 20 | r.sex = sex 21 | r.age = age 22 | } 23 | 24 | //SetWorkExperience 设置工作经历 25 | func (r *Resume) SetWorkExperience(timeArea, company string) { 26 | r.timeArea = timeArea 27 | r.company = company 28 | } 29 | 30 | //Display 显示 31 | func (r *Resume) Display() { 32 | fmt.Printf("%s %s %s\n", r.name, r.sex, r.age) 33 | fmt.Printf("工作经历:%s %s\n", r.timeArea, r.company) 34 | } 35 | 36 | func (r *Resume) Clone() Prototype { 37 | tc := *r 38 | return &tc 39 | } 40 | 41 | func ExamplePrototype() { 42 | manager = NewConcretePrototype() 43 | 44 | a := &Resume{ 45 | name: "大鸟", 46 | } 47 | manager.Set("a", a) 48 | a.SetPersonalInfo("男", "29") 49 | a.SetWorkExperience("1998-2000", "XX公司") 50 | 51 | b := manager.Get("a").Clone().(*Resume) 52 | b.SetWorkExperience("1998-2006", "YY企业") 53 | 54 | c := manager.Get("a").Clone().(*Resume) 55 | a.Display() 56 | b.Display() 57 | c.Display() 58 | // OutPut: 59 | // 大鸟 男 29 60 | // 工作经历:1998-2000 XX公司 61 | // 大鸟 男 29 62 | // 工作经历:1998-2006 YY企业 63 | // 大鸟 男 29 64 | // 工作经历:1998-2000 XX公司 65 | } 66 | -------------------------------------------------------------------------------- /09_原型模式/9.5_浅度复制和深度复制/prototype.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | //Prototype 原型 4 | type Prototype interface { 5 | Clone() Prototype 6 | } 7 | 8 | //ConcretePrototype 具体对象 9 | type ConcretePrototype struct { 10 | pMap map[string]Prototype 11 | } 12 | 13 | //NewConcretePrototype ConcretePrototype构造函数 14 | func NewConcretePrototype() *ConcretePrototype { 15 | return &ConcretePrototype{ 16 | pMap: make(map[string]Prototype), 17 | } 18 | } 19 | 20 | //Get 获取对象 21 | func (c *ConcretePrototype) Get(id string) Prototype { 22 | return c.pMap[id] 23 | } 24 | 25 | //Set 设置对象 26 | func (c *ConcretePrototype) Set(id string, cloneable Prototype) { 27 | c.pMap[id] = cloneable 28 | } 29 | -------------------------------------------------------------------------------- /09_原型模式/9.5_浅度复制和深度复制/prototype_test.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | var manager *ConcretePrototype 9 | 10 | //Type1 浅度复制,Type3为引用 11 | type Type1 struct { 12 | name string 13 | *Type3 14 | } 15 | 16 | func (t *Type1) Clone() Prototype { 17 | tc := *t 18 | return &tc 19 | } 20 | 21 | //Type2 深度复制,Type3为值 22 | type Type2 struct { 23 | name string 24 | Type3 25 | } 26 | 27 | func (t *Type2) Clone() Prototype { 28 | tc := *t 29 | return &tc 30 | } 31 | 32 | type Type3 struct { 33 | id string 34 | } 35 | 36 | //TestClone1 浅度复制测试 37 | func TestClone1(t *testing.T) { 38 | manager = NewConcretePrototype() 39 | 40 | a := &Type1{ 41 | name: "type1", 42 | Type3: &Type3{id: "t3"}, 43 | } 44 | manager.Set("t1", a) 45 | t1 := manager.Get("t1") 46 | t2 := t1.Clone() 47 | 48 | if t1 == t2 { 49 | t.Fatal("error! 浅度复制出错") 50 | } 51 | if &t1 == &t2 { 52 | t.Fatal("error! 浅度复制出错") 53 | } 54 | 55 | type1 := t1.(*Type1) 56 | type2 := t2.(*Type1) 57 | 58 | type1.name = "t1_name" 59 | if type1.name == type2.name { 60 | t.Fatal("error! 浅度复制出错") 61 | } 62 | type1.Type3.id = "t1_id" 63 | if type1.Type3.id != type2.Type3.id { 64 | fmt.Println(type1.Type3.id) 65 | fmt.Println(type2.Type3.id) 66 | t.Fatal("error! 浅度复制出错!t3为引用,type1.t3.id == type2.t3.id") 67 | } 68 | } 69 | 70 | //TestClone2 深度复制测试 71 | func TestClone2(t *testing.T) { 72 | manager = NewConcretePrototype() 73 | 74 | a := &Type2{ 75 | name: "type2", 76 | Type3: Type3{id: "t3"}, //此处改成传值 77 | } 78 | manager.Set("t1", a) 79 | t1 := manager.Get("t1") 80 | t2 := t1.Clone() 81 | 82 | if t1 == t2 { 83 | t.Fatal("error! 深度复制出错") 84 | } 85 | if &t1 == &t2 { 86 | t.Fatal("error! 深度复制出错") 87 | } 88 | 89 | type1 := t1.(*Type2) 90 | type2 := t2.(*Type2) 91 | 92 | type1.name = "t1_name" 93 | if type1.name == type2.name { 94 | t.Fatal("error! 深度复制出错") 95 | } 96 | type1.Type3.id = "t1_id" 97 | if type1.Type3.id == type2.Type3.id { 98 | fmt.Println(type1.Type3.id) 99 | fmt.Println(type2.Type3.id) 100 | t.Fatal("error! 深度复制出错!t3为值传递,type1.t3.id != type2.t3.id") 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /09_原型模式/README.md: -------------------------------------------------------------------------------- 1 | ### 原型模式 2 | 3 | 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 -------------------------------------------------------------------------------- /10_模板方法/10.2_重复等于易做加难改/templatemethod.go: -------------------------------------------------------------------------------- 1 | package templatemethod 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | //TestPaperA 学生甲抄的试卷 8 | type TestPaperA struct { 9 | } 10 | 11 | //TestQuestion1 试题1 12 | func (*TestPaperA) TestQuestion1() { 13 | fmt.Println(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维") 14 | fmt.Println("答案:b") 15 | } 16 | 17 | //TestQuestion2 试题2 18 | func (*TestPaperA) TestQuestion2() { 19 | fmt.Println(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化") 20 | fmt.Println("答案:a") 21 | } 22 | 23 | //TestQuestion3 试题3 24 | func (*TestPaperA) TestQuestion3() { 25 | fmt.Println(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对") 26 | fmt.Println("答案:c") 27 | } 28 | 29 | //TestPaperB 学生甲抄的试卷 30 | type TestPaperB struct { 31 | } 32 | 33 | //TestQuestion1 试题1 34 | func (*TestPaperB) TestQuestion1() { 35 | fmt.Println(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维") 36 | fmt.Println("答案:d") 37 | } 38 | 39 | //TestQuestion2 试题2 40 | func (*TestPaperB) TestQuestion2() { 41 | fmt.Println(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化") 42 | fmt.Println("答案:b") 43 | } 44 | 45 | //TestQuestion3 试题3 46 | func (*TestPaperB) TestQuestion3() { 47 | fmt.Println(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对") 48 | fmt.Println("答案:a") 49 | } 50 | -------------------------------------------------------------------------------- /10_模板方法/10.2_重复等于易做加难改/templatemethod_test.go: -------------------------------------------------------------------------------- 1 | package templatemethod 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func ExampleTemplatemethod() { 8 | fmt.Println("学生甲抄的试卷:") 9 | studentA := new(TestPaperA) 10 | studentA.TestQuestion1() 11 | studentA.TestQuestion2() 12 | studentA.TestQuestion3() 13 | 14 | fmt.Println("学生乙抄的试卷:") 15 | studentB := new(TestPaperB) 16 | studentB.TestQuestion1() 17 | studentB.TestQuestion2() 18 | studentB.TestQuestion3() 19 | // OutPut: 20 | // 学生甲抄的试卷: 21 | // 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 22 | // 答案:b 23 | // 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 24 | // 答案:a 25 | // 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 26 | // 答案:c 27 | // 学生乙抄的试卷: 28 | // 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 29 | // 答案:d 30 | // 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 31 | // 答案:b 32 | // 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 33 | // 答案:a 34 | } 35 | -------------------------------------------------------------------------------- /10_模板方法/10.3_提炼代码(模板方法)/templatemethod.go: -------------------------------------------------------------------------------- 1 | package templatemethod 2 | 3 | import "fmt" 4 | 5 | //ITestQuestion 试卷问题 6 | type ITestQuestion interface { 7 | TestQuestion1() 8 | TestQuestion2() 9 | TestQuestion3() 10 | } 11 | 12 | //IAnswer 答案接口 13 | type IAnswer interface { 14 | Answer1() string 15 | Answer2() string 16 | Answer3() string 17 | } 18 | 19 | //TestPaper 试卷模板 20 | type TestPaper struct { 21 | IAnswer 22 | } 23 | 24 | //NewTestPaper TestPaper构造函数 25 | func NewTestPaper(answer IAnswer) *TestPaper { 26 | return &TestPaper{ 27 | IAnswer: answer, 28 | } 29 | } 30 | 31 | //TestQuestion1 试题1 32 | func (t *TestPaper) TestQuestion1() { 33 | fmt.Println(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维") 34 | fmt.Printf("答案:%s\n", t.IAnswer.Answer1()) 35 | } 36 | 37 | //TestQuestion2 试题2 38 | func (t *TestPaper) TestQuestion2() { 39 | fmt.Println(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化") 40 | fmt.Printf("答案:%s\n", t.IAnswer.Answer2()) 41 | } 42 | 43 | //TestQuestion3 试题3 44 | func (t *TestPaper) TestQuestion3() { 45 | fmt.Println(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对") 46 | fmt.Printf("答案:%s\n", t.IAnswer.Answer3()) 47 | } 48 | 49 | //TestPaperA 试卷A 50 | type TestPaperA struct { 51 | *TestPaper 52 | } 53 | 54 | //NewTestPaperA TestPaperA构造函数 55 | func NewTestPaperA() ITestQuestion { 56 | paperA := new(TestPaperA) 57 | testPaper := NewTestPaper(paperA) 58 | paperA.TestPaper = testPaper 59 | return paperA 60 | } 61 | 62 | //Answer1 答案1 63 | func (*TestPaperA) Answer1() string { 64 | return "b" 65 | } 66 | 67 | //Answer2 答案2 68 | func (*TestPaperA) Answer2() string { 69 | return "c" 70 | } 71 | 72 | //Answer3 答案3 73 | func (*TestPaperA) Answer3() string { 74 | return "a" 75 | } 76 | 77 | //TestPaperB 试卷B 78 | type TestPaperB struct { 79 | *TestPaper 80 | } 81 | 82 | //NewTestPaperB TestPaperB构造函数 83 | func NewTestPaperB() ITestQuestion { 84 | paperB := new(TestPaperB) 85 | testPaper := NewTestPaper(paperB) 86 | paperB.TestPaper = testPaper 87 | return paperB 88 | } 89 | 90 | //Answer1 答案1 91 | func (*TestPaperB) Answer1() string { 92 | return "c" 93 | } 94 | 95 | //Answer2 答案2 96 | func (*TestPaperB) Answer2() string { 97 | return "a" 98 | } 99 | 100 | //Answer3 答案3 101 | func (*TestPaperB) Answer3() string { 102 | return "a" 103 | } 104 | -------------------------------------------------------------------------------- /10_模板方法/10.3_提炼代码(模板方法)/templatemethod_test.go: -------------------------------------------------------------------------------- 1 | package templatemethod 2 | 3 | import "fmt" 4 | 5 | func ExampleTemplatemethod() { 6 | fmt.Println("学生甲抄的试卷:") 7 | studentA := NewTestPaperA() 8 | studentA.TestQuestion1() 9 | studentA.TestQuestion2() 10 | studentA.TestQuestion3() 11 | 12 | fmt.Println("学生乙抄的试卷:") 13 | studentB := NewTestPaperB() 14 | studentB.TestQuestion1() 15 | studentB.TestQuestion2() 16 | studentB.TestQuestion3() 17 | // OutPut: 18 | // 学生甲抄的试卷: 19 | // 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 20 | // 答案:b 21 | // 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 22 | // 答案:c 23 | // 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 24 | // 答案:a 25 | // 学生乙抄的试卷: 26 | // 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 27 | // 答案:c 28 | // 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 29 | // 答案:a 30 | // 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 31 | // 答案:a 32 | } 33 | -------------------------------------------------------------------------------- /10_模板方法/10.3_提炼代码(策略模式)/templatemethod.go: -------------------------------------------------------------------------------- 1 | package templatemethod 2 | 3 | import "fmt" 4 | 5 | //IAnswer 答案接口 6 | type IAnswer interface { 7 | Answer1() string 8 | Answer2() string 9 | Answer3() string 10 | } 11 | 12 | //TestPaper 金庸小说考题试卷 13 | type TestPaper struct { 14 | IAnswer 15 | } 16 | 17 | //NewTestPaper TestPaper构造函数 18 | func NewTestPaper(answer IAnswer) *TestPaper { 19 | return &TestPaper{ 20 | IAnswer: answer, 21 | } 22 | } 23 | 24 | //TestQuestion1 试题1 25 | func (t *TestPaper) TestQuestion1() { 26 | fmt.Println(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维") 27 | fmt.Printf("答案:%s\n", t.IAnswer.Answer1()) 28 | } 29 | 30 | //TestQuestion2 试题2 31 | func (t *TestPaper) TestQuestion2() { 32 | fmt.Println(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化") 33 | fmt.Printf("答案:%s\n", t.IAnswer.Answer2()) 34 | } 35 | 36 | //TestQuestion3 试题3 37 | func (t *TestPaper) TestQuestion3() { 38 | fmt.Println(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对") 39 | fmt.Printf("答案:%s\n", t.IAnswer.Answer3()) 40 | } 41 | 42 | //TestPaperA 试卷A 43 | type TestPaperA struct { 44 | } 45 | 46 | //Answer1 答案1 47 | func (*TestPaperA) Answer1() string { 48 | return "b" 49 | } 50 | 51 | //Answer2 答案2 52 | func (*TestPaperA) Answer2() string { 53 | return "c" 54 | } 55 | 56 | //Answer3 答案3 57 | func (*TestPaperA) Answer3() string { 58 | return "a" 59 | } 60 | 61 | //TestPaperB 试卷B 62 | type TestPaperB struct { 63 | } 64 | 65 | //Answer1 答案1 66 | func (*TestPaperB) Answer1() string { 67 | return "c" 68 | } 69 | 70 | //Answer2 答案2 71 | func (*TestPaperB) Answer2() string { 72 | return "a" 73 | } 74 | 75 | //Answer3 答案3 76 | func (*TestPaperB) Answer3() string { 77 | return "a" 78 | } 79 | -------------------------------------------------------------------------------- /10_模板方法/10.3_提炼代码(策略模式)/templatemethod_test.go: -------------------------------------------------------------------------------- 1 | package templatemethod 2 | 3 | import "fmt" 4 | 5 | func ExampleTemplatemethod() { 6 | fmt.Println("学生甲抄的试卷:") 7 | studentA := NewTestPaper(new(TestPaperA)) 8 | studentA.TestQuestion1() 9 | studentA.TestQuestion2() 10 | studentA.TestQuestion3() 11 | 12 | fmt.Println("学生乙抄的试卷:") 13 | studentB := NewTestPaper(new(TestPaperB)) 14 | studentB.TestQuestion1() 15 | studentB.TestQuestion2() 16 | studentB.TestQuestion3() 17 | // OutPut: 18 | // 学生甲抄的试卷: 19 | // 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 20 | // 答案:b 21 | // 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 22 | // 答案:c 23 | // 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 24 | // 答案:a 25 | // 学生乙抄的试卷: 26 | // 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 27 | // 答案:c 28 | // 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 29 | // 答案:a 30 | // 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 31 | // 答案:a 32 | } 33 | -------------------------------------------------------------------------------- /10_模板方法/10_4模板方法模式/templatemethod.go: -------------------------------------------------------------------------------- 1 | package templatemethod 2 | 3 | import "fmt" 4 | 5 | //IAbstractMethod 抽象方法接口 6 | type IAbstractMethod interface { 7 | PrimitiveOperation1() 8 | PrimitiveOperation2() 9 | } 10 | 11 | //ITemplateMethod 模板方法接口 12 | type ITemplateMethod interface { 13 | TemplateMethod() 14 | } 15 | 16 | //Template 模板 17 | type Template struct { 18 | IAbstractMethod 19 | } 20 | 21 | //NewTemplate Template构造函数 22 | func NewTemplate(abstractMethod IAbstractMethod) *Template { 23 | return &Template{ 24 | IAbstractMethod: abstractMethod, 25 | } 26 | } 27 | 28 | //TemplateMethod 模板的方法 29 | func (t *Template) TemplateMethod() { 30 | t.IAbstractMethod.PrimitiveOperation1() 31 | t.IAbstractMethod.PrimitiveOperation2() 32 | } 33 | 34 | //ConcreteClassA 具体类A 35 | type ConcreteClassA struct { 36 | *Template 37 | } 38 | 39 | //NewConcreteClassA ConcreteClassA构造函数 40 | func NewConcreteClassA() ITemplateMethod { 41 | classA := &ConcreteClassA{} 42 | template := NewTemplate(classA) 43 | classA.Template = template 44 | return classA 45 | } 46 | 47 | //PrimitiveOperation1 方法1 48 | func (*ConcreteClassA) PrimitiveOperation1() { 49 | fmt.Println("具体类A方法1实现") 50 | } 51 | 52 | //PrimitiveOperation2 方法2 53 | func (*ConcreteClassA) PrimitiveOperation2() { 54 | fmt.Println("具体类A方法2实现") 55 | } 56 | 57 | //ConcreteClassB 具体类B 58 | type ConcreteClassB struct { 59 | *Template 60 | } 61 | 62 | //NewConcreteClassB ConcreteClassB构造函数 63 | func NewConcreteClassB() ITemplateMethod { 64 | classB := &ConcreteClassB{} 65 | template := NewTemplate(classB) 66 | classB.Template = template 67 | return classB 68 | } 69 | 70 | //PrimitiveOperation1 方法1 71 | func (*ConcreteClassB) PrimitiveOperation1() { 72 | fmt.Println("具体类B方法1实现") 73 | } 74 | 75 | //PrimitiveOperation2 方法2 76 | func (*ConcreteClassB) PrimitiveOperation2() { 77 | fmt.Println("具体类B方法2实现") 78 | } 79 | -------------------------------------------------------------------------------- /10_模板方法/10_4模板方法模式/templatemethod_test.go: -------------------------------------------------------------------------------- 1 | package templatemethod 2 | 3 | func ExampleTemplatemethod() { 4 | c := NewConcreteClassA() 5 | c.TemplateMethod() 6 | 7 | c = NewConcreteClassB() 8 | c.TemplateMethod() 9 | 10 | // OutPut: 11 | // 具体类A方法1实现 12 | // 具体类A方法2实现 13 | // 具体类B方法1实现 14 | // 具体类B方法2实现 15 | } 16 | -------------------------------------------------------------------------------- /10_模板方法/README.md: -------------------------------------------------------------------------------- 1 | ### 模板方法 2 | 3 | 并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。 -------------------------------------------------------------------------------- /11_迪米特法则/README.md: -------------------------------------------------------------------------------- 1 | ### 迪米特法则(Law of Demeter) 2 | 3 | 如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。 -------------------------------------------------------------------------------- /12_外观模式/12.2_股民炒股代码/facade.go: -------------------------------------------------------------------------------- 1 | package facade 2 | 3 | import "fmt" 4 | 5 | //Stock1 股票1 6 | type Stock1 struct { 7 | } 8 | 9 | //Sell 卖出 10 | func (*Stock1) Sell() { 11 | fmt.Println("股票1卖出") 12 | } 13 | 14 | //Buy 买股票 15 | func (*Stock1) Buy() { 16 | fmt.Println("股票1买入") 17 | } 18 | 19 | //Stock2 股票2 20 | type Stock2 struct { 21 | } 22 | 23 | //Sell 卖出 24 | func (*Stock2) Sell() { 25 | fmt.Println("股票2卖出") 26 | } 27 | 28 | //Buy 买股票 29 | func (*Stock2) Buy() { 30 | fmt.Println("股票2买入") 31 | } 32 | 33 | //Stock3 股票3 34 | type Stock3 struct { 35 | } 36 | 37 | //Sell 卖出 38 | func (*Stock3) Sell() { 39 | fmt.Println("股票3卖出") 40 | } 41 | 42 | //Buy 买股票 43 | func (*Stock3) Buy() { 44 | fmt.Println("股票3买入") 45 | } 46 | 47 | //NationalDebt1 国债1 48 | type NationalDebt1 struct { 49 | } 50 | 51 | //Sell 卖国债 52 | func (*NationalDebt1) Sell() { 53 | fmt.Println("国债1卖出") 54 | } 55 | 56 | //Buy 买国债 57 | func (*NationalDebt1) Buy() { 58 | fmt.Println("国债1买入") 59 | } 60 | 61 | //Realty1 房地产1 62 | type Realty1 struct { 63 | } 64 | 65 | //Sell 卖出 66 | func (*Realty1) Sell() { 67 | fmt.Println("房产1卖出") 68 | } 69 | 70 | //Buy 买股票 71 | func (*Realty1) Buy() { 72 | fmt.Println("房产1买入") 73 | } 74 | -------------------------------------------------------------------------------- /12_外观模式/12.2_股民炒股代码/facade_test.go: -------------------------------------------------------------------------------- 1 | package facade 2 | 3 | func ExampleFacade() { 4 | gu1 := new(Stock1) 5 | gu2 := new(Stock2) 6 | gu3 := new(Stock3) 7 | nd1 := new(NationalDebt1) 8 | rt1 := new(Realty1) 9 | 10 | gu1.Buy() 11 | gu2.Buy() 12 | gu3.Buy() 13 | nd1.Buy() 14 | rt1.Buy() 15 | 16 | gu1.Sell() 17 | gu2.Sell() 18 | gu3.Sell() 19 | nd1.Sell() 20 | rt1.Sell() 21 | 22 | // OutPut: 23 | // 股票1买入 24 | // 股票2买入 25 | // 股票3买入 26 | // 国债1买入 27 | // 房产1买入 28 | // 股票1卖出 29 | // 股票2卖出 30 | // 股票3卖出 31 | // 国债1卖出 32 | // 房产1卖出 33 | } 34 | -------------------------------------------------------------------------------- /12_外观模式/12.3_投资资金代码/facade.go: -------------------------------------------------------------------------------- 1 | package facade 2 | 3 | import "fmt" 4 | 5 | //Fund 基金 6 | type Fund struct { 7 | gu1 *Stock1 8 | gu2 *Stock2 9 | gu3 *Stock3 10 | nd1 *NationalDebt1 11 | rt1 *Realty1 12 | } 13 | 14 | //NewFund Fund构造函数 15 | func NewFund() *Fund { 16 | return &Fund{ 17 | gu1: new(Stock1), 18 | gu2: new(Stock2), 19 | gu3: new(Stock3), 20 | nd1: new(NationalDebt1), 21 | rt1: new(Realty1), 22 | } 23 | } 24 | 25 | //BuyFund 买基金 26 | func (f *Fund) BuyFund() { 27 | f.gu1.Buy() 28 | f.gu2.Buy() 29 | f.gu3.Buy() 30 | f.nd1.Buy() 31 | f.rt1.Buy() 32 | } 33 | 34 | //SellFund 卖基金 35 | func (f *Fund) SellFund() { 36 | f.gu1.Sell() 37 | f.gu2.Sell() 38 | f.gu3.Sell() 39 | f.nd1.Sell() 40 | f.rt1.Sell() 41 | } 42 | 43 | //Stock1 股票1 44 | type Stock1 struct { 45 | } 46 | 47 | //Sell 卖出 48 | func (*Stock1) Sell() { 49 | fmt.Println("股票1卖出") 50 | } 51 | 52 | //Buy 买股票 53 | func (*Stock1) Buy() { 54 | fmt.Println("股票1买入") 55 | } 56 | 57 | //Stock2 股票2 58 | type Stock2 struct { 59 | } 60 | 61 | //Sell 卖出 62 | func (*Stock2) Sell() { 63 | fmt.Println("股票2卖出") 64 | } 65 | 66 | //Buy 买股票 67 | func (*Stock2) Buy() { 68 | fmt.Println("股票2买入") 69 | } 70 | 71 | //Stock3 股票3 72 | type Stock3 struct { 73 | } 74 | 75 | //Sell 卖出 76 | func (*Stock3) Sell() { 77 | fmt.Println("股票3卖出") 78 | } 79 | 80 | //Buy 买股票 81 | func (*Stock3) Buy() { 82 | fmt.Println("股票3买入") 83 | } 84 | 85 | //NationalDebt1 国债1 86 | type NationalDebt1 struct { 87 | } 88 | 89 | //Sell 卖国债 90 | func (*NationalDebt1) Sell() { 91 | fmt.Println("国债1卖出") 92 | } 93 | 94 | //Buy 买国债 95 | func (*NationalDebt1) Buy() { 96 | fmt.Println("国债1买入") 97 | } 98 | 99 | //Realty1 房地产1 100 | type Realty1 struct { 101 | } 102 | 103 | //Sell 卖出 104 | func (*Realty1) Sell() { 105 | fmt.Println("房产1卖出") 106 | } 107 | 108 | //Buy 买股票 109 | func (*Realty1) Buy() { 110 | fmt.Println("房产1买入") 111 | } 112 | -------------------------------------------------------------------------------- /12_外观模式/12.3_投资资金代码/facade_test.go: -------------------------------------------------------------------------------- 1 | package facade 2 | 3 | func ExampleFacade() { 4 | jijin := new(Fund) 5 | 6 | jijin.BuyFund() 7 | jijin.SellFund() 8 | 9 | // OutPut: 10 | // 股票1买入 11 | // 股票2买入 12 | // 股票3买入 13 | // 国债1买入 14 | // 房产1买入 15 | // 股票1卖出 16 | // 股票2卖出 17 | // 股票3卖出 18 | // 国债1卖出 19 | // 房产1卖出 20 | } 21 | -------------------------------------------------------------------------------- /12_外观模式/12.4_外观模式/facade.go: -------------------------------------------------------------------------------- 1 | package facade 2 | 3 | import "fmt" 4 | 5 | //SubSystemOne 子系统一 6 | type SubSystemOne struct { 7 | } 8 | 9 | //MethodOne 子系统方法一 10 | func (*SubSystemOne) MethodOne() { 11 | fmt.Println("子系统方法一") 12 | } 13 | 14 | //SubSystemTwo 子系统二 15 | type SubSystemTwo struct { 16 | } 17 | 18 | //MethodTwo 子系统方法二 19 | func (*SubSystemTwo) MethodTwo() { 20 | fmt.Println("子系统方法二") 21 | } 22 | 23 | //SubSystemThree 子系统三 24 | type SubSystemThree struct { 25 | } 26 | 27 | //MethodThree 子系统方法三 28 | func (*SubSystemThree) MethodThree() { 29 | fmt.Println("子系统方法三") 30 | } 31 | 32 | //SubSystemFour 子系统四 33 | type SubSystemFour struct { 34 | } 35 | 36 | //MethodFour 子系统方法四 37 | func (*SubSystemFour) MethodFour() { 38 | fmt.Println("子系统方法四") 39 | } 40 | 41 | //Facade 外观 42 | type Facade struct { 43 | one *SubSystemOne 44 | two *SubSystemTwo 45 | three *SubSystemThree 46 | four *SubSystemFour 47 | } 48 | 49 | //NewFacade 构造函数 50 | func NewFacade() *Facade { 51 | return &Facade{ 52 | one: new(SubSystemOne), 53 | two: new(SubSystemTwo), 54 | three: new(SubSystemThree), 55 | four: new(SubSystemFour), 56 | } 57 | } 58 | 59 | //MethodA 方法组A 60 | func (f *Facade) MethodA() { 61 | fmt.Println("方法组A()----") 62 | f.one.MethodOne() 63 | f.two.MethodTwo() 64 | f.four.MethodFour() 65 | } 66 | 67 | //MethodB 方法组B 68 | func (f *Facade) MethodB() { 69 | fmt.Println("方法组B()----") 70 | f.two.MethodTwo() 71 | f.three.MethodThree() 72 | } 73 | -------------------------------------------------------------------------------- /12_外观模式/12.4_外观模式/facade_test.go: -------------------------------------------------------------------------------- 1 | package facade 2 | 3 | func ExampleFacade() { 4 | facade := new(Facade) 5 | 6 | facade.MethodA() 7 | facade.MethodB() 8 | 9 | // OutPut: 10 | // 方法组A()---- 11 | // 子系统方法一 12 | // 子系统方法二 13 | // 子系统方法四 14 | // 方法组B()---- 15 | // 子系统方法二 16 | // 子系统方法三 17 | } 18 | -------------------------------------------------------------------------------- /12_外观模式/README.md: -------------------------------------------------------------------------------- 1 | ### 外观模式(Facade Pattern) 2 | 3 | 外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 -------------------------------------------------------------------------------- /13_建造者模式/13.6_建造者模式/builder.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | import "fmt" 4 | 5 | //Product 产品 6 | type Product struct { 7 | parts []string 8 | } 9 | 10 | //Add 添加产品 11 | func (p *Product) Add(part string) { 12 | p.parts = append(p.parts, part) 13 | } 14 | 15 | //Show 展示产品 16 | func (p *Product) Show() { 17 | fmt.Println("产品 创建 ----") 18 | for _, part := range p.parts { 19 | fmt.Println(part) 20 | } 21 | } 22 | 23 | //Builder 建造接口 24 | type Builder interface { 25 | BuildPartA() 26 | BuildPartB() 27 | GetResult() *Product 28 | } 29 | 30 | //ConcreteBuilder1 具体产品建造 31 | type ConcreteBuilder1 struct { 32 | product *Product 33 | } 34 | 35 | //NewConcreteBuilder1 ConcreteBuilder1构造函数 36 | func NewConcreteBuilder1() *ConcreteBuilder1 { 37 | return &ConcreteBuilder1{ 38 | product: new(Product), 39 | } 40 | } 41 | 42 | //BuildPartA 建造部件A 43 | func (c *ConcreteBuilder1) BuildPartA() { 44 | c.product.Add("部件A") 45 | } 46 | 47 | //BuildPartB 建造部件B 48 | func (c *ConcreteBuilder1) BuildPartB() { 49 | c.product.Add("部件B") 50 | } 51 | 52 | //GetResult 返回产品 53 | func (c *ConcreteBuilder1) GetResult() *Product { 54 | return c.product 55 | } 56 | 57 | //ConcreteBuilder2 具体产品建造 58 | type ConcreteBuilder2 struct { 59 | product *Product 60 | } 61 | 62 | //NewConcreteBuilder2 ConcreteBuilder2构造函数 63 | func NewConcreteBuilder2() *ConcreteBuilder2 { 64 | return &ConcreteBuilder2{ 65 | product: new(Product), 66 | } 67 | } 68 | 69 | //BuildPartA 建造部件X 70 | func (c *ConcreteBuilder2) BuildPartA() { 71 | c.product.Add("部件X") 72 | } 73 | 74 | //BuildPartB 建造部件Y 75 | func (c *ConcreteBuilder2) BuildPartB() { 76 | c.product.Add("部件Y") 77 | } 78 | 79 | //GetResult 返回产品 80 | func (c *ConcreteBuilder2) GetResult() *Product { 81 | return c.product 82 | } 83 | 84 | //Director 指挥者 85 | type Director struct { 86 | } 87 | 88 | //Construct 指挥建造过程 89 | func (*Director) Construct(builder Builder) { 90 | builder.BuildPartA() 91 | builder.BuildPartB() 92 | } 93 | -------------------------------------------------------------------------------- /13_建造者模式/13.6_建造者模式/builder_test.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | func ExampleBuild() { 4 | director := new(Director) 5 | 6 | b1 := NewConcreteBuilder1() 7 | director.Construct(b1) 8 | p1 := b1.GetResult() 9 | p1.Show() 10 | 11 | b2 := NewConcreteBuilder2() 12 | director.Construct(b2) 13 | p2 := b2.GetResult() 14 | p2.Show() 15 | 16 | // OutPut: 17 | // 产品 创建 ---- 18 | // 部件A 19 | // 部件B 20 | // 产品 创建 ---- 21 | // 部件X 22 | // 部件Y 23 | } 24 | -------------------------------------------------------------------------------- /13_建造者模式/README.md: -------------------------------------------------------------------------------- 1 | ### 造者模式(Builder Pattern) 2 | 3 | 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 4 | 5 | 建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。 -------------------------------------------------------------------------------- /13_建造者模式/建造者模式(常规实现)/builder.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | //Builder 是生成器接口 4 | type Builder interface { 5 | Part1() 6 | Part2() 7 | Part3() 8 | } 9 | 10 | //Director 指挥者 11 | type Director struct { 12 | builder Builder 13 | } 14 | 15 | // NewDirector ... 16 | func NewDirector(builder Builder) *Director { 17 | return &Director{ 18 | builder: builder, 19 | } 20 | } 21 | 22 | //Construct Product 23 | func (d *Director) Construct() { 24 | d.builder.Part1() 25 | d.builder.Part2() 26 | d.builder.Part3() 27 | } 28 | 29 | type Builder1 struct { 30 | result string 31 | } 32 | 33 | func (b *Builder1) Part1() { 34 | b.result += "1" 35 | } 36 | 37 | func (b *Builder1) Part2() { 38 | b.result += "2" 39 | } 40 | 41 | func (b *Builder1) Part3() { 42 | b.result += "3" 43 | } 44 | 45 | func (b *Builder1) GetResult() string { 46 | return b.result 47 | } 48 | 49 | type Builder2 struct { 50 | result int 51 | } 52 | 53 | func (b *Builder2) Part1() { 54 | b.result += 1 55 | } 56 | 57 | func (b *Builder2) Part2() { 58 | b.result += 2 59 | } 60 | 61 | func (b *Builder2) Part3() { 62 | b.result += 3 63 | } 64 | 65 | func (b *Builder2) GetResult() int { 66 | return b.result 67 | } 68 | -------------------------------------------------------------------------------- /13_建造者模式/建造者模式(常规实现)/builder_test.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | import "testing" 4 | 5 | func TestBuilder1(t *testing.T) { 6 | builder := new(Builder1) 7 | director := NewDirector(builder) 8 | director.Construct() 9 | res := builder.GetResult() 10 | if res != "123" { 11 | t.Fatalf("Builder1 fail expect 123 acture %s", res) 12 | } 13 | } 14 | 15 | func TestBuilder2(t *testing.T) { 16 | builder := new(Builder2) 17 | director := NewDirector(builder) 18 | director.Construct() 19 | res := builder.GetResult() 20 | if res != 6 { 21 | t.Fatalf("Builder2 fail expect 6 acture %d", res) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /14_观察者模式/14.2_双向耦合代码/obserser.go: -------------------------------------------------------------------------------- 1 | package obserser 2 | 3 | import "fmt" 4 | 5 | //Secretary 前台秘书类 6 | type Secretary struct { 7 | observers []*StockObserver 8 | Action string 9 | } 10 | 11 | //Attach 增加 12 | func (s *Secretary) Attach(stockObserver *StockObserver) { 13 | s.observers = append(s.observers, stockObserver) 14 | } 15 | 16 | //Detach 移除 17 | func (s *Secretary) Detach(stockObserver *StockObserver) { 18 | // s.observers.Remove(stockObserver) 19 | for index, val := range s.observers { 20 | if val == stockObserver { 21 | s.observers = append(s.observers[:index], s.observers[index+1:]...) 22 | break 23 | } 24 | } 25 | } 26 | 27 | //Notify 通知 28 | func (s *Secretary) Notify() { 29 | for _, val := range s.observers { 30 | val.Update() 31 | } 32 | } 33 | 34 | //StockObserver 看股票的同事 35 | type StockObserver struct { 36 | name string 37 | *Secretary 38 | } 39 | 40 | //NewStockObserver StockObserver构造函数 41 | func NewStockObserver(name string, s *Secretary) *StockObserver { 42 | return &StockObserver{ 43 | name: name, 44 | Secretary: s, 45 | } 46 | } 47 | 48 | //Update 更新状态 49 | func (s *StockObserver) Update() { 50 | fmt.Printf("%s %s 关闭股票行情,继续工作!\n", s.Secretary.Action, s.name) 51 | } 52 | -------------------------------------------------------------------------------- /14_观察者模式/14.2_双向耦合代码/obserser_test.go: -------------------------------------------------------------------------------- 1 | package obserser 2 | 3 | func ExampleObserser() { 4 | //前台小姐童子喆 5 | tongzizhe := new(Secretary) 6 | //看股票的同事 7 | tongshi1 := NewStockObserver("魏关姹", tongzizhe) 8 | tongshi2 := NewStockObserver("易管查", tongzizhe) 9 | 10 | //前台记下了两位同事 11 | tongzizhe.Attach(tongshi1) 12 | tongzizhe.Attach(tongshi2) 13 | //发现老板回来 14 | tongzizhe.Action = "老板回来了!" 15 | //通知两个同事 16 | tongzizhe.Notify() 17 | 18 | // OutPut: 19 | // 老板回来了! 魏关姹 关闭股票行情,继续工作! 20 | // 老板回来了! 易管查 关闭股票行情,继续工作! 21 | } 22 | -------------------------------------------------------------------------------- /14_观察者模式/14.3_解耦观察者/obserser.go: -------------------------------------------------------------------------------- 1 | package obserser 2 | 3 | import "fmt" 4 | 5 | //Observer 观察者接口 6 | type Observer interface { 7 | Update() 8 | } 9 | 10 | //Secretary 前台秘书类 11 | type Secretary struct { 12 | observers []Observer 13 | Action string 14 | } 15 | 16 | //Attach 增加 17 | func (s *Secretary) Attach(observer Observer) { 18 | s.observers = append(s.observers, observer) 19 | } 20 | 21 | //Detach 移除 22 | func (s *Secretary) Detach(observer Observer) { 23 | for index, val := range s.observers { 24 | if val == observer { 25 | s.observers = append(s.observers[:index], s.observers[index+1:]...) 26 | break 27 | } 28 | } 29 | } 30 | 31 | //Notify 通知 32 | func (s *Secretary) Notify() { 33 | for _, val := range s.observers { 34 | val.Update() 35 | } 36 | } 37 | 38 | //StockObserver 看股票的同事 39 | type StockObserver struct { 40 | name string 41 | *Secretary 42 | } 43 | 44 | //NewStockObserver StockObserver构造函数 45 | func NewStockObserver(name string, s *Secretary) *StockObserver { 46 | return &StockObserver{ 47 | name: name, 48 | Secretary: s, 49 | } 50 | } 51 | 52 | //Update 更新状态 53 | func (s *StockObserver) Update() { 54 | fmt.Printf("%s %s 关闭股票行情,继续工作!\n", s.Secretary.Action, s.name) 55 | } 56 | 57 | //NBAObserver 看NBA的同事 58 | type NBAObserver struct { 59 | name string 60 | *Secretary 61 | } 62 | 63 | //NewNBAObserver NBAObserver 64 | func NewNBAObserver(name string, s *Secretary) *NBAObserver { 65 | return &NBAObserver{ 66 | name: name, 67 | Secretary: s, 68 | } 69 | } 70 | 71 | //Update 更新状态 72 | func (s *NBAObserver) Update() { 73 | fmt.Printf("%s %s 关闭NBA直播,继续工作!\n", s.Secretary.Action, s.name) 74 | } 75 | -------------------------------------------------------------------------------- /14_观察者模式/14.3_解耦观察者/obserser_test.go: -------------------------------------------------------------------------------- 1 | package obserser 2 | 3 | func ExampleObserser() { 4 | //前台小姐童子喆 5 | tongzizhe := new(Secretary) 6 | //看股票的同事 7 | tongshi1 := NewStockObserver("魏关姹", tongzizhe) 8 | //看NBA的同事 9 | tongshi2 := NewNBAObserver("易管查", tongzizhe) 10 | 11 | //前台记下了两位同事 12 | tongzizhe.Attach(tongshi1) 13 | tongzizhe.Attach(tongshi2) 14 | //发现老板回来 15 | tongzizhe.Action = "老板回来了!" 16 | //通知两个同事 17 | tongzizhe.Notify() 18 | 19 | // OutPut: 20 | // 老板回来了! 魏关姹 关闭股票行情,继续工作! 21 | // 老板回来了! 易管查 关闭NBA直播,继续工作! 22 | } 23 | -------------------------------------------------------------------------------- /14_观察者模式/14.4_双向解耦/obserser.go: -------------------------------------------------------------------------------- 1 | package obserser 2 | 3 | import "fmt" 4 | 5 | //Observer 观察者接口 6 | type Observer interface { 7 | Update() 8 | } 9 | 10 | //Subject 通知者接口 11 | type Subject interface { 12 | Attach(observer Observer) 13 | Detach(observer Observer) 14 | Notify() 15 | SubjectState() string 16 | } 17 | 18 | //Secretary 前台秘书类 19 | type Secretary struct { 20 | observers []Observer 21 | Action string 22 | } 23 | 24 | //Attach 增加 25 | func (s *Secretary) Attach(observer Observer) { 26 | s.observers = append(s.observers, observer) 27 | } 28 | 29 | //Detach 移除 30 | func (s *Secretary) Detach(observer Observer) { 31 | for index, val := range s.observers { 32 | if val == observer { 33 | s.observers = append(s.observers[:index], s.observers[index+1:]...) 34 | break 35 | } 36 | } 37 | } 38 | 39 | //Notify 通知 40 | func (s *Secretary) Notify() { 41 | for _, val := range s.observers { 42 | val.Update() 43 | } 44 | } 45 | 46 | //SubjectState 消息 47 | func (s *Secretary) SubjectState() string { 48 | return s.Action 49 | } 50 | 51 | //Boss 老板 52 | type Boss struct { 53 | observers []Observer 54 | Action string 55 | } 56 | 57 | //Attach 增加 58 | func (s *Boss) Attach(observer Observer) { 59 | s.observers = append(s.observers, observer) 60 | } 61 | 62 | //Detach 移除 63 | func (s *Boss) Detach(observer Observer) { 64 | for index, val := range s.observers { 65 | if val == observer { 66 | s.observers = append(s.observers[:index], s.observers[index+1:]...) 67 | break 68 | } 69 | } 70 | } 71 | 72 | //Notify 通知 73 | func (s *Boss) Notify() { 74 | for _, val := range s.observers { 75 | val.Update() 76 | } 77 | } 78 | 79 | //SubjectState 消息 80 | func (s *Boss) SubjectState() string { 81 | return s.Action 82 | } 83 | 84 | //StockObserver 看股票的同事 85 | type StockObserver struct { 86 | name string 87 | Subject 88 | } 89 | 90 | //NewStockObserver StockObserver构造函数 91 | func NewStockObserver(name string, s Subject) *StockObserver { 92 | return &StockObserver{ 93 | name: name, 94 | Subject: s, 95 | } 96 | } 97 | 98 | //Update 更新状态 99 | func (s *StockObserver) Update() { 100 | fmt.Printf("%s %s 关闭股票行情,继续工作!\n", s.Subject.SubjectState(), s.name) 101 | } 102 | 103 | //NBAObserver 看NBA的同事 104 | type NBAObserver struct { 105 | name string 106 | Subject 107 | } 108 | 109 | //NewNBAObserver NBAObserver 110 | func NewNBAObserver(name string, s Subject) *NBAObserver { 111 | return &NBAObserver{ 112 | name: name, 113 | Subject: s, 114 | } 115 | } 116 | 117 | //Update 更新状态 118 | func (s *NBAObserver) Update() { 119 | fmt.Printf("%s %s 关闭NBA直播,继续工作!\n", s.Subject.SubjectState(), s.name) 120 | } 121 | -------------------------------------------------------------------------------- /14_观察者模式/14.4_双向解耦/obserser_test.go: -------------------------------------------------------------------------------- 1 | package obserser 2 | 3 | func ExampleObserser() { 4 | //前台小姐童子喆 5 | tongzizhe := new(Secretary) 6 | //看股票的同事 7 | tongshi1 := NewStockObserver("魏关姹", tongzizhe) 8 | //看NBA的同事 9 | tongshi2 := NewNBAObserver("易管查", tongzizhe) 10 | 11 | //前台记下了两位同事 12 | tongzizhe.Attach(tongshi1) 13 | tongzizhe.Attach(tongshi2) 14 | //发现老板回来 15 | tongzizhe.Action = "老板回来了!" 16 | //通知两个同事 17 | tongzizhe.Notify() 18 | 19 | //老板胡汉三 20 | boos := new(Boss) 21 | //看股票的同事 22 | tongshi1 = NewStockObserver("魏关姹", boos) 23 | //看NBA的同事 24 | tongshi2 = NewNBAObserver("易管查", boos) 25 | 26 | boos.Attach(tongshi1) 27 | boos.Attach(tongshi2) 28 | 29 | boos.Detach(tongshi1) 30 | 31 | //老板回来了 32 | boos.Action = "我胡汉三回来了!" 33 | //发出通知 34 | boos.Notify() 35 | 36 | // OutPut: 37 | // 老板回来了! 魏关姹 关闭股票行情,继续工作! 38 | // 老板回来了! 易管查 关闭NBA直播,继续工作! 39 | // 我胡汉三回来了! 易管查 关闭NBA直播,继续工作! 40 | } 41 | -------------------------------------------------------------------------------- /14_观察者模式/README.md: -------------------------------------------------------------------------------- 1 | ### 观察者模式(Observer Pattern) 2 | 3 | 定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅。 -------------------------------------------------------------------------------- /14_观察者模式/观察者模式(常规实现)/obserser.go: -------------------------------------------------------------------------------- 1 | package observer 2 | 3 | import "fmt" 4 | 5 | //Subject 通知者 6 | type Subject struct { 7 | observers []Observer 8 | context string 9 | } 10 | 11 | //NewSubject Subject构造函数 12 | func NewSubject() *Subject { 13 | return &Subject{ 14 | observers: make([]Observer, 0), 15 | } 16 | } 17 | 18 | //Attach 添加 19 | func (s *Subject) Attach(o Observer) { 20 | s.observers = append(s.observers, o) 21 | } 22 | 23 | //notify 通知 24 | func (s *Subject) notify() { 25 | for _, o := range s.observers { 26 | o.Update(s) 27 | } 28 | } 29 | 30 | //UpdateContext 发出通知 31 | func (s *Subject) UpdateContext(context string) { 32 | s.context = context 33 | s.notify() 34 | } 35 | 36 | //Observer 观察者接口 37 | type Observer interface { 38 | Update(*Subject) 39 | } 40 | 41 | //Reader 订阅者 42 | type Reader struct { 43 | name string 44 | } 45 | 46 | //NewReader Reader构造函数 47 | func NewReader(name string) *Reader { 48 | return &Reader{ 49 | name: name, 50 | } 51 | } 52 | 53 | //Update 订阅者更新状态 54 | func (r *Reader) Update(s *Subject) { 55 | fmt.Printf("%s receive %s\n", r.name, s.context) 56 | } 57 | -------------------------------------------------------------------------------- /14_观察者模式/观察者模式(常规实现)/obserser_test.go: -------------------------------------------------------------------------------- 1 | package observer 2 | 3 | func ExampleObserver() { 4 | subject := NewSubject() 5 | reader1 := NewReader("reader1") 6 | reader2 := NewReader("reader2") 7 | reader3 := NewReader("reader3") 8 | subject.Attach(reader1) 9 | subject.Attach(reader2) 10 | subject.Attach(reader3) 11 | 12 | subject.UpdateContext("observer mode") 13 | // Output: 14 | // reader1 receive observer mode 15 | // reader2 receive observer mode 16 | // reader3 receive observer mode 17 | } 18 | -------------------------------------------------------------------------------- /15_抽象工厂模式/15.2_数据库访问程序/abstractfactory.go: -------------------------------------------------------------------------------- 1 | package abstractfactory 2 | 3 | import ( 4 | "design-pattern-go/15_抽象工厂模式/model" 5 | "fmt" 6 | ) 7 | 8 | //SqlserverUser Sqlserver数据库 9 | type SqlserverUser struct { 10 | } 11 | 12 | //Insert 插入用户 13 | func (*SqlserverUser) Insert(user *model.User) { 14 | fmt.Println("在Sqlserver中给User表增加一条记录") 15 | } 16 | 17 | //GetUser 获取用户 18 | func (*SqlserverUser) GetUser(id int) *model.User { 19 | fmt.Println("在Sqlserver中根据ID得到User表一条记录") 20 | return new(model.User) 21 | } 22 | -------------------------------------------------------------------------------- /15_抽象工厂模式/15.2_数据库访问程序/abstractfactory_test.go: -------------------------------------------------------------------------------- 1 | package abstractfactory 2 | 3 | import "design-pattern-go/15_抽象工厂模式/model" 4 | 5 | func ExampleAbstractfactory() { 6 | user := new(model.User) 7 | 8 | su := new(SqlserverUser) 9 | su.Insert(user) 10 | su.GetUser(1) 11 | 12 | // OutPut: 13 | // 在Sqlserver中给User表增加一条记录 14 | // 在Sqlserver中根据ID得到User表一条记录 15 | } 16 | -------------------------------------------------------------------------------- /15_抽象工厂模式/15.3_工厂方法模式访问数据库/abstractfactory.go: -------------------------------------------------------------------------------- 1 | package abstractfactory 2 | 3 | import ( 4 | "design-pattern-go/15_抽象工厂模式/model" 5 | "fmt" 6 | ) 7 | 8 | //IUser 用户接口 9 | type IUser interface { 10 | Insert(user *model.User) 11 | GetUser(id int) *model.User 12 | } 13 | 14 | //SqlserverUser Sqlserver数据库 15 | type SqlserverUser struct { 16 | } 17 | 18 | //Insert 插入用户 19 | func (*SqlserverUser) Insert(user *model.User) { 20 | fmt.Println("在Sqlserver中给User表增加一条记录") 21 | } 22 | 23 | //GetUser 获取用户 24 | func (*SqlserverUser) GetUser(id int) *model.User { 25 | fmt.Println("在Sqlserver中根据ID得到User表一条记录") 26 | return new(model.User) 27 | } 28 | 29 | //AccessUser Access 30 | type AccessUser struct { 31 | } 32 | 33 | //Insert 插入用户 34 | func (*AccessUser) Insert(user *model.User) { 35 | fmt.Println("在Access中给User表增加一条记录") 36 | } 37 | 38 | //GetUser 获取用户 39 | func (*AccessUser) GetUser(id int) *model.User { 40 | fmt.Println("在Access中根据ID得到User表一条记录") 41 | return new(model.User) 42 | } 43 | 44 | //IFactory IUser工厂接口 45 | type IFactory interface { 46 | CreateUser() IUser 47 | } 48 | 49 | type SqlserverFactory struct { 50 | } 51 | 52 | func (*SqlserverFactory) CreateUser() IUser { 53 | return new(SqlserverUser) 54 | } 55 | 56 | type AccessFactory struct { 57 | } 58 | 59 | func (*AccessFactory) CreateUser() IUser { 60 | return new(AccessUser) 61 | } 62 | -------------------------------------------------------------------------------- /15_抽象工厂模式/15.3_工厂方法模式访问数据库/abstractfactory_test.go: -------------------------------------------------------------------------------- 1 | package abstractfactory 2 | 3 | import "design-pattern-go/15_抽象工厂模式/model" 4 | 5 | func ExampleAbstractfactory() { 6 | user := new(model.User) 7 | 8 | factory := new(SqlserverFactory) 9 | su := factory.CreateUser() 10 | su.Insert(user) 11 | su.GetUser(1) 12 | 13 | // OutPut: 14 | // 在Sqlserver中给User表增加一条记录 15 | // 在Sqlserver中根据ID得到User表一条记录 16 | } 17 | -------------------------------------------------------------------------------- /15_抽象工厂模式/15.4_抽象工厂方法访问数据库/abstractfactory.go: -------------------------------------------------------------------------------- 1 | package abstractfactory 2 | 3 | import ( 4 | "design-pattern-go/15_抽象工厂模式/model" 5 | "fmt" 6 | ) 7 | 8 | //IUser 用户接口 9 | type IUser interface { 10 | Insert(user *model.User) 11 | GetUser(id int) *model.User 12 | } 13 | 14 | //SqlserverUser Sqlserver数据库 15 | type SqlserverUser struct { 16 | } 17 | 18 | //Insert 插入用户 19 | func (*SqlserverUser) Insert(user *model.User) { 20 | fmt.Println("在Sqlserver中给User表增加一条记录") 21 | } 22 | 23 | //GetUser 获取用户 24 | func (*SqlserverUser) GetUser(id int) *model.User { 25 | fmt.Println("在Sqlserver中根据ID得到User表一条记录") 26 | return new(model.User) 27 | } 28 | 29 | //AccessUser Access 30 | type AccessUser struct { 31 | } 32 | 33 | //Insert 插入用户 34 | func (*AccessUser) Insert(user *model.User) { 35 | fmt.Println("在Access中给User表增加一条记录") 36 | } 37 | 38 | //GetUser 获取用户 39 | func (*AccessUser) GetUser(id int) *model.User { 40 | fmt.Println("在Access中根据ID得到User表一条记录") 41 | return new(model.User) 42 | } 43 | 44 | //IDepartment 部门接口 45 | type IDepartment interface { 46 | Insert(user *model.Department) 47 | GetDepartment(id int) *model.Department 48 | } 49 | 50 | //SqlserverDepartment Sqlserver数据库 51 | type SqlserverDepartment struct { 52 | } 53 | 54 | //Insert 插入部门 55 | func (*SqlserverDepartment) Insert(user *model.Department) { 56 | fmt.Println("在Sqlserver中给Department表增加一条记录") 57 | } 58 | 59 | //GetDepartment 获取部门 60 | func (*SqlserverDepartment) GetDepartment(id int) *model.Department { 61 | fmt.Println("在Sqlserver中根据ID得到Department表一条记录") 62 | return new(model.Department) 63 | } 64 | 65 | //AccessDepartment Access 66 | type AccessDepartment struct { 67 | } 68 | 69 | //Insert 插入部门 70 | func (*AccessDepartment) Insert(user *model.Department) { 71 | fmt.Println("在Access中给Department表增加一条记录") 72 | } 73 | 74 | //GetDepartment 获取部门 75 | func (*AccessDepartment) GetDepartment(id int) *model.Department { 76 | fmt.Println("在Access中根据ID得到Department表一条记录") 77 | return new(model.Department) 78 | } 79 | 80 | //IFactory IUser工厂接口 81 | type IFactory interface { 82 | CreateUser() IUser 83 | CreateDepartment() IDepartment 84 | } 85 | 86 | type SqlserverFactory struct { 87 | } 88 | 89 | func (*SqlserverFactory) CreateUser() IUser { 90 | return new(SqlserverUser) 91 | } 92 | 93 | func (*SqlserverFactory) CreateDepartment() IDepartment { 94 | return new(SqlserverDepartment) 95 | } 96 | 97 | type AccessFactory struct { 98 | } 99 | 100 | func (*AccessFactory) CreateUser() IUser { 101 | return new(AccessUser) 102 | } 103 | 104 | func (*AccessFactory) CreateDepartment() IDepartment { 105 | return new(AccessDepartment) 106 | } 107 | -------------------------------------------------------------------------------- /15_抽象工厂模式/15.4_抽象工厂方法访问数据库/abstractfactory_test.go: -------------------------------------------------------------------------------- 1 | package abstractfactory 2 | 3 | import "design-pattern-go/15_抽象工厂模式/model" 4 | 5 | func ExampleAbstractfactory() { 6 | user := new(model.User) 7 | dept := new(model.Department) 8 | 9 | factory := new(SqlserverFactory) 10 | su := factory.CreateUser() 11 | su.Insert(user) 12 | su.GetUser(1) 13 | 14 | id := factory.CreateDepartment() 15 | id.Insert(dept) 16 | id.GetDepartment(1) 17 | 18 | // OutPut: 19 | // 在Sqlserver中给User表增加一条记录 20 | // 在Sqlserver中根据ID得到User表一条记录 21 | // 在Sqlserver中给Department表增加一条记录 22 | // 在Sqlserver中根据ID得到Department表一条记录 23 | } 24 | -------------------------------------------------------------------------------- /15_抽象工厂模式/README.md: -------------------------------------------------------------------------------- 1 | ### 抽象工厂模式(Abstract Factory Pattern) 2 | 3 | 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。 -------------------------------------------------------------------------------- /15_抽象工厂模式/model/department.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | //Department 部门信息 4 | type Department struct { 5 | ID int `json:"id"` 6 | DeptName string `json:"dept_name"` 7 | } 8 | -------------------------------------------------------------------------------- /15_抽象工厂模式/model/user.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | //User 用户信息 4 | type User struct { 5 | ID int `json:"id"` 6 | Name string `json:"name"` 7 | } 8 | -------------------------------------------------------------------------------- /16_状态模式/16.5_状态模式(常规实现)/state.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | //State 状态接口 9 | type State interface { 10 | Handle(context *Context) 11 | } 12 | 13 | //ConcreteStateA 具体状态A 14 | type ConcreteStateA struct { 15 | } 16 | 17 | //Handle 处理状态 18 | func (*ConcreteStateA) Handle(context *Context) { 19 | context.SetState(new(ConcreteStateB)) 20 | } 21 | 22 | //ConcreteStateB 具体状态B 23 | type ConcreteStateB struct { 24 | } 25 | 26 | //Handle 处理状态 27 | func (*ConcreteStateB) Handle(context *Context) { 28 | context.SetState(new(ConcreteStateA)) 29 | } 30 | 31 | type Context struct { 32 | State 33 | } 34 | 35 | func NewContext(state State) *Context { 36 | return &Context{ 37 | State: state, 38 | } 39 | } 40 | 41 | func (c *Context) GetState() State { 42 | return c.State 43 | } 44 | 45 | func (c *Context) SetState(state State) { 46 | c.State = state 47 | fmt.Printf("当前状态:%s\n", reflect.TypeOf(state).Elem().Name()) 48 | } 49 | 50 | func (c *Context) Request() { 51 | c.State.Handle(c) 52 | } 53 | -------------------------------------------------------------------------------- /16_状态模式/16.5_状态模式(常规实现)/state_test.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | func ExampleState() { 4 | c := NewContext(new(ConcreteStateA)) 5 | c.Request() 6 | c.Request() 7 | c.Request() 8 | c.Request() 9 | 10 | // OutPut: 11 | // 当前状态:ConcreteStateB 12 | // 当前状态:ConcreteStateA 13 | // 当前状态:ConcreteStateB 14 | // 当前状态:ConcreteStateA 15 | } 16 | -------------------------------------------------------------------------------- /16_状态模式/16.7_工作状态-状态模式/state.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import "fmt" 4 | 5 | //State 抽象状态 6 | type State interface { 7 | WriteProgram(w *Work) 8 | } 9 | 10 | //ForenoonState 上午工作状态 11 | type ForenoonState struct { 12 | } 13 | 14 | //WriteProgram 工作状态 15 | func (*ForenoonState) WriteProgram(w *Work) { 16 | if w.Hour < 12 { 17 | fmt.Printf("当前时间:%g点 上午工作,精神百倍\n", w.Hour) 18 | } else { 19 | w.SetState(new(NoonState)) 20 | w.WriteProgram() 21 | } 22 | } 23 | 24 | //NoonState 中午工作状态 25 | type NoonState struct { 26 | } 27 | 28 | //WriteProgram 工作状态 29 | func (*NoonState) WriteProgram(w *Work) { 30 | if w.Hour < 13 { 31 | fmt.Printf("当前时间:%g点 饿了,午饭;犯困,午休。\n", w.Hour) 32 | } else { 33 | w.SetState(new(AfternoonState)) 34 | w.WriteProgram() 35 | } 36 | } 37 | 38 | //AfternoonState 下午工作状态 39 | type AfternoonState struct { 40 | } 41 | 42 | //WriteProgram 工作状态 43 | func (*AfternoonState) WriteProgram(w *Work) { 44 | if w.Hour < 17 { 45 | fmt.Printf("当前时间:%g点 下午状态还不错,继续努力\n", w.Hour) 46 | } else { 47 | w.SetState(new(EveningState)) 48 | w.WriteProgram() 49 | } 50 | } 51 | 52 | //EveningState 晚间工作状态 53 | type EveningState struct { 54 | } 55 | 56 | //WriteProgram 工作状态 57 | func (*EveningState) WriteProgram(w *Work) { 58 | if w.TaskFinished { 59 | w.SetState(new(RestState)) 60 | w.WriteProgram() 61 | } else { 62 | if w.Hour < 21 { 63 | fmt.Printf("当前时间:%g点 加班哦,疲累之极\n", w.Hour) 64 | } else { 65 | w.SetState(new(SleepingState)) 66 | w.WriteProgram() 67 | } 68 | } 69 | } 70 | 71 | //SleepingState 睡眠状态 72 | type SleepingState struct { 73 | } 74 | 75 | //WriteProgram 工作状态 76 | func (*SleepingState) WriteProgram(w *Work) { 77 | fmt.Printf("当前时间:%g点 不行了,睡着了。\n", w.Hour) 78 | } 79 | 80 | //RestState 下班休息状态 81 | type RestState struct { 82 | } 83 | 84 | //WriteProgram 工作状态 85 | func (*RestState) WriteProgram(w *Work) { 86 | fmt.Printf("当前时间:%g点 下班回家了\n", w.Hour) 87 | } 88 | 89 | //Work 工作 90 | type Work struct { 91 | current State 92 | Hour float64 93 | TaskFinished bool 94 | } 95 | 96 | // NewWork 构造函数 97 | func NewWork() *Work { 98 | return &Work{ 99 | current: new(ForenoonState), 100 | } 101 | } 102 | 103 | //SetState 设置状态 104 | func (w *Work) SetState(s State) { 105 | w.current = s 106 | } 107 | 108 | //WriteProgram 工作状态 109 | func (w *Work) WriteProgram() { 110 | w.current.WriteProgram(w) 111 | } 112 | -------------------------------------------------------------------------------- /16_状态模式/16.7_工作状态-状态模式/state_test.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | func ExampleState() { 4 | emergencyProjects := NewWork() 5 | emergencyProjects.Hour = 9 6 | emergencyProjects.WriteProgram() 7 | emergencyProjects.Hour = 10 8 | emergencyProjects.WriteProgram() 9 | emergencyProjects.Hour = 12 10 | emergencyProjects.WriteProgram() 11 | emergencyProjects.Hour = 13 12 | emergencyProjects.WriteProgram() 13 | emergencyProjects.Hour = 14 14 | emergencyProjects.WriteProgram() 15 | emergencyProjects.Hour = 17 16 | 17 | //emergencyProjects.WorkFinished = true 18 | emergencyProjects.TaskFinished = false 19 | 20 | emergencyProjects.WriteProgram() 21 | emergencyProjects.Hour = 19 22 | emergencyProjects.WriteProgram() 23 | emergencyProjects.Hour = 22 24 | emergencyProjects.WriteProgram() 25 | 26 | // OutPut: 27 | // 当前时间:9点 上午工作,精神百倍 28 | // 当前时间:10点 上午工作,精神百倍 29 | // 当前时间:12点 饿了,午饭;犯困,午休。 30 | // 当前时间:13点 下午状态还不错,继续努力 31 | // 当前时间:14点 下午状态还不错,继续努力 32 | // 当前时间:17点 加班哦,疲累之极 33 | // 当前时间:19点 加班哦,疲累之极 34 | // 当前时间:22点 不行了,睡着了。 35 | } 36 | -------------------------------------------------------------------------------- /16_状态模式/README.md: -------------------------------------------------------------------------------- 1 | ### 状态模式(State Pattern) 2 | 3 | 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。 -------------------------------------------------------------------------------- /17_适配器模式/17.2_适配器模式(常规实现)/adapter.go: -------------------------------------------------------------------------------- 1 | package adapter 2 | 3 | import "fmt" 4 | 5 | //Target 是适配的目标接口 6 | type Target interface { 7 | Request() 8 | } 9 | 10 | //Adaptee 是被适配的目标接口 11 | type Adaptee interface { 12 | SpecificRequest() 13 | } 14 | 15 | //NewAdaptee 是被适配接口的工厂函数 16 | func NewAdaptee() Adaptee { 17 | return new(adapteeImpl) 18 | } 19 | 20 | //AdapteeImpl 是被适配的目标类 21 | type adapteeImpl struct{} 22 | 23 | //SpecificRequest 是目标类的一个方法 24 | func (*adapteeImpl) SpecificRequest() { 25 | fmt.Println("特殊请求") 26 | } 27 | 28 | //NewAdapter 是Adapter的工厂函数 29 | func NewAdapter(adaptee Adaptee) Target { 30 | return &adapter{ 31 | Adaptee: adaptee, 32 | } 33 | } 34 | 35 | //Adapter 是转换Adaptee为Target接口的适配器 36 | type adapter struct { 37 | Adaptee 38 | } 39 | 40 | //Request 实现Target接口 41 | func (a *adapter) Request() { 42 | a.SpecificRequest() 43 | } 44 | -------------------------------------------------------------------------------- /17_适配器模式/17.2_适配器模式(常规实现)/adapter_test.go: -------------------------------------------------------------------------------- 1 | package adapter 2 | 3 | func ExampleAdapter() { 4 | adaptee := NewAdaptee() 5 | target := NewAdapter(adaptee) 6 | target.Request() 7 | 8 | // OutPut: 9 | // 特殊请求 10 | } 11 | -------------------------------------------------------------------------------- /17_适配器模式/17.4_篮球翻译适配器/adapter.go: -------------------------------------------------------------------------------- 1 | package adapter 2 | 3 | import "fmt" 4 | 5 | //Player 篮球运动员接口 6 | type Player interface { 7 | Attack() 8 | Defense() 9 | } 10 | 11 | //Forwards 前锋 12 | type Forwards struct { 13 | Name string 14 | } 15 | 16 | //Attack 进攻 17 | func (a *Forwards) Attack() { 18 | fmt.Printf("前锋 %s 进攻\n", a.Name) 19 | } 20 | 21 | //Defense 防守 22 | func (a *Forwards) Defense() { 23 | fmt.Printf("前锋 %s 防守\n", a.Name) 24 | } 25 | 26 | //Center 中锋 27 | type Center struct { 28 | Name string 29 | } 30 | 31 | //Attack 进攻 32 | func (c *Center) Attack() { 33 | fmt.Printf("中锋 %s 进攻\n", c.Name) 34 | } 35 | 36 | //Defense 防守 37 | func (c *Center) Defense() { 38 | fmt.Printf("中锋 %s 防守\n", c.Name) 39 | } 40 | 41 | //Guards 后卫 42 | type Guards struct { 43 | Name string 44 | } 45 | 46 | //Attack 进攻 47 | func (g *Guards) Attack() { 48 | fmt.Printf("后卫 %s 进攻\n", g.Name) 49 | } 50 | 51 | //Defense 防守 52 | func (g *Guards) Defense() { 53 | fmt.Printf("后卫 %s 防守\n", g.Name) 54 | } 55 | 56 | //ForeignCenter 外籍中锋 57 | type ForeignCenter struct { 58 | Name string 59 | } 60 | 61 | //Attack 进攻 62 | func (f *ForeignCenter) 进攻() { 63 | fmt.Printf("外籍中锋 %s 进攻\n", f.Name) 64 | } 65 | 66 | //Defense 防守 67 | func (f *ForeignCenter) 防守() { 68 | fmt.Printf("外籍中锋 %s 防守\n", f.Name) 69 | } 70 | 71 | //NewTranslator 构造函数 72 | func NewTranslator(name string) *Translator { 73 | return &Translator{ 74 | wjzf: &ForeignCenter{ 75 | Name: name, 76 | }, 77 | } 78 | } 79 | 80 | //Translator 翻译者 81 | type Translator struct { 82 | wjzf *ForeignCenter 83 | } 84 | 85 | //Attack 进攻 86 | func (t *Translator) Attack() { 87 | t.wjzf.进攻() 88 | } 89 | 90 | //Defense 防守 91 | func (t *Translator) Defense() { 92 | t.wjzf.防守() 93 | } 94 | -------------------------------------------------------------------------------- /17_适配器模式/17.4_篮球翻译适配器/adapter_test.go: -------------------------------------------------------------------------------- 1 | package adapter 2 | 3 | func ExampleAdapter() { 4 | b := new(Forwards) 5 | b.Name = "巴蒂尔" 6 | b.Attack() 7 | 8 | m := new(Guards) 9 | m.Name = "麦克格雷迪" 10 | m.Attack() 11 | 12 | ym := NewTranslator("姚明") 13 | ym.Attack() 14 | ym.Defense() 15 | 16 | // OutPut: 17 | // 前锋 巴蒂尔 进攻 18 | // 后卫 麦克格雷迪 进攻 19 | // 外籍中锋 姚明 进攻 20 | // 外籍中锋 姚明 防守 21 | } 22 | -------------------------------------------------------------------------------- /17_适配器模式/README.md: -------------------------------------------------------------------------------- 1 | ### 适配器模式(Adapter Pattern) 2 | 3 | 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。 -------------------------------------------------------------------------------- /18_备忘录模式/18.2_游戏存进度/memento.go: -------------------------------------------------------------------------------- 1 | package memento 2 | 3 | import "fmt" 4 | 5 | //GameRole 角色 6 | type GameRole struct { 7 | //生命力 8 | Vitality int 9 | //攻击力 10 | Attack int 11 | //防御力 12 | Defense int 13 | } 14 | 15 | //StateDisplay 状态显示 16 | func (g *GameRole) StateDisplay() { 17 | fmt.Printf("角色当前状态:\n") 18 | fmt.Printf("体力:%d\n", g.Vitality) 19 | fmt.Printf("攻击力:%d\n", g.Attack) 20 | fmt.Printf("防御力:%d\n", g.Defense) 21 | fmt.Println("") 22 | } 23 | 24 | //GetInitState 获得初始状态 25 | func (g *GameRole) GetInitState() { 26 | g.Vitality = 100 27 | g.Attack = 100 28 | g.Defense = 100 29 | } 30 | 31 | //Fight 战斗 32 | func (g *GameRole) Fight() { 33 | g.Vitality = 0 34 | g.Attack = 0 35 | g.Defense = 0 36 | } 37 | -------------------------------------------------------------------------------- /18_备忘录模式/18.2_游戏存进度/memento_test.go: -------------------------------------------------------------------------------- 1 | package memento 2 | 3 | func ExampleMemento() { 4 | //大战Boss前 5 | lixiaoyao := new(GameRole) 6 | lixiaoyao.GetInitState() 7 | lixiaoyao.StateDisplay() 8 | 9 | //保存进度 10 | backup := new(GameRole) 11 | backup.Vitality = lixiaoyao.Vitality 12 | backup.Attack = lixiaoyao.Attack 13 | backup.Defense = lixiaoyao.Defense 14 | 15 | //大战Boss时,损耗严重 16 | lixiaoyao.Fight() 17 | lixiaoyao.StateDisplay() 18 | 19 | //恢复之前状态 20 | lixiaoyao.Vitality = backup.Vitality 21 | lixiaoyao.Attack = backup.Attack 22 | lixiaoyao.Defense = backup.Defense 23 | 24 | lixiaoyao.StateDisplay() 25 | 26 | // OutPut: 27 | // 角色当前状态: 28 | // 体力:100 29 | // 攻击力:100 30 | // 防御力:100 31 | // 32 | // 角色当前状态: 33 | // 体力:0 34 | // 攻击力:0 35 | // 防御力:0 36 | // 37 | // 角色当前状态: 38 | // 体力:100 39 | // 攻击力:100 40 | // 防御力:100 41 | } 42 | -------------------------------------------------------------------------------- /18_备忘录模式/18.4_备忘录模式(常规实现)/memento.go: -------------------------------------------------------------------------------- 1 | package memento 2 | 3 | import "fmt" 4 | 5 | //Originator 发起人 6 | type Originator struct { 7 | State string 8 | } 9 | 10 | //CreateMemento 构造函数 11 | func (o *Originator) CreateMemento() *Memento { 12 | return &Memento{ 13 | State: o.State, 14 | } 15 | } 16 | 17 | //SetMemento 设置备忘录 18 | func (o *Originator) SetMemento(memento *Memento) { 19 | o.State = memento.State 20 | } 21 | 22 | //Show 展示 23 | func (o *Originator) Show() { 24 | fmt.Println("State=" + o.State) 25 | } 26 | 27 | //Memento 备忘录 28 | type Memento struct { 29 | State string 30 | } 31 | 32 | //Caretaker 管理者 33 | type Caretaker struct { 34 | *Memento 35 | } 36 | -------------------------------------------------------------------------------- /18_备忘录模式/18.4_备忘录模式(常规实现)/memento_test.go: -------------------------------------------------------------------------------- 1 | package memento 2 | 3 | func ExampleMemento() { 4 | o := new(Originator) 5 | o.State = "On" 6 | o.Show() 7 | 8 | c := new(Caretaker) 9 | c.Memento = o.CreateMemento() 10 | 11 | o.State = "Off" 12 | o.Show() 13 | 14 | o.SetMemento(c.Memento) 15 | o.Show() 16 | 17 | // OutPut: 18 | // State=On 19 | // State=Off 20 | // State=On 21 | } 22 | -------------------------------------------------------------------------------- /18_备忘录模式/18.5_游戏进度备忘/memento.go: -------------------------------------------------------------------------------- 1 | package memento 2 | 3 | import "fmt" 4 | 5 | //GameRole 角色 6 | type GameRole struct { 7 | //生命力 8 | Vitality int 9 | //攻击力 10 | Attack int 11 | //防御力 12 | Defense int 13 | } 14 | 15 | //StateDisplay 状态显示 16 | func (g *GameRole) StateDisplay() { 17 | fmt.Printf("角色当前状态:\n") 18 | fmt.Printf("体力:%d\n", g.Vitality) 19 | fmt.Printf("攻击力:%d\n", g.Attack) 20 | fmt.Printf("防御力:%d\n", g.Defense) 21 | fmt.Println("") 22 | } 23 | 24 | //GetInitState 获得初始状态 25 | func (g *GameRole) GetInitState() { 26 | g.Vitality = 100 27 | g.Attack = 100 28 | g.Defense = 100 29 | } 30 | 31 | //Fight 战斗 32 | func (g *GameRole) Fight() { 33 | g.Vitality = 0 34 | g.Attack = 0 35 | g.Defense = 0 36 | } 37 | 38 | //SaveState 保存角色状态 39 | func (g *GameRole) SaveState() *RoleStateMemento { 40 | return &RoleStateMemento{ 41 | Vitality: g.Vitality, 42 | Attack: g.Attack, 43 | Defense: g.Defense, 44 | } 45 | } 46 | 47 | //RecoveryState 恢复角色状态 48 | func (g *GameRole) RecoveryState(memento *RoleStateMemento) { 49 | g.Vitality = memento.Vitality 50 | g.Attack = memento.Attack 51 | g.Defense = memento.Defense 52 | } 53 | 54 | //RoleStateMemento 角色状态存储箱 55 | type RoleStateMemento struct { 56 | //生命力 57 | Vitality int 58 | //攻击力 59 | Attack int 60 | //防御力 61 | Defense int 62 | } 63 | 64 | //RoleStateCaretaker 角色状态管理者 65 | type RoleStateCaretaker struct { 66 | Memento *RoleStateMemento 67 | } 68 | -------------------------------------------------------------------------------- /18_备忘录模式/18.5_游戏进度备忘/memento_test.go: -------------------------------------------------------------------------------- 1 | package memento 2 | 3 | func ExampleMemento() { 4 | //大战Boss前 5 | lixiaoyao := new(GameRole) 6 | lixiaoyao.GetInitState() 7 | lixiaoyao.StateDisplay() 8 | 9 | //保存进度 10 | stateAdmin := new(RoleStateCaretaker) 11 | stateAdmin.Memento = lixiaoyao.SaveState() 12 | 13 | //大战Boss时,损耗严重 14 | lixiaoyao.Fight() 15 | lixiaoyao.StateDisplay() 16 | 17 | //恢复之前状态 18 | lixiaoyao.RecoveryState(stateAdmin.Memento) 19 | 20 | lixiaoyao.StateDisplay() 21 | 22 | // OutPut: 23 | // 角色当前状态: 24 | // 体力:100 25 | // 攻击力:100 26 | // 防御力:100 27 | // 28 | // 角色当前状态: 29 | // 体力:0 30 | // 攻击力:0 31 | // 防御力:0 32 | // 33 | // 角色当前状态: 34 | // 体力:100 35 | // 攻击力:100 36 | // 防御力:100 37 | } 38 | -------------------------------------------------------------------------------- /18_备忘录模式/README.md: -------------------------------------------------------------------------------- 1 | ### 备忘录模式 2 | 3 | 在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 -------------------------------------------------------------------------------- /19_组合模式/19.2_组合模式(常规实现)/composite.go: -------------------------------------------------------------------------------- 1 | package composite 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | //Component 接口 9 | type Component interface { 10 | Add(c Component) 11 | Remove(c Component) 12 | Display(depth int) 13 | } 14 | 15 | //Composite 组合 16 | type Composite struct { 17 | name string 18 | children []Component 19 | } 20 | 21 | //Add 添加 22 | func (c *Composite) Add(component Component) { 23 | c.children = append(c.children, component) 24 | } 25 | 26 | //Remove 移除 27 | func (c *Composite) Remove(component Component) { 28 | for index, val := range c.children { 29 | if component == val { 30 | c.children = append(c.children[0:index], c.children[index+1:]...) 31 | break 32 | } 33 | } 34 | } 35 | 36 | //Display 展示 37 | func (c *Composite) Display(depth int) { 38 | fmt.Println(strings.Repeat("-", depth) + c.name) 39 | for _, component := range c.children { 40 | component.Display(depth + 2) 41 | } 42 | } 43 | 44 | //Leaf 叶子 45 | type Leaf struct { 46 | name string 47 | } 48 | 49 | //Add 添加 50 | func (*Leaf) Add(c Component) { 51 | fmt.Println("Cannot add to a leaf") 52 | } 53 | 54 | //Remove 移除 55 | func (*Leaf) Remove(c Component) { 56 | fmt.Println("Cannot remove from a leaf") 57 | } 58 | 59 | //Display 展示 60 | func (l *Leaf) Display(depth int) { 61 | fmt.Println(strings.Repeat("-", depth) + l.name) 62 | } 63 | -------------------------------------------------------------------------------- /19_组合模式/19.2_组合模式(常规实现)/composite_test.go: -------------------------------------------------------------------------------- 1 | package composite 2 | 3 | func ExampleComposite() { 4 | root := &Composite{name: "root"} 5 | root.Add(&Leaf{name: "Leaf A"}) 6 | root.Add(&Leaf{name: "Leaf B"}) 7 | 8 | comp := &Composite{name: "Composite X"} 9 | comp.Add(&Leaf{name: "Leaf XA"}) 10 | comp.Add(&Leaf{name: "Leaf XB"}) 11 | 12 | root.Add(comp) 13 | 14 | comp2 := &Composite{name: "Composite XY"} 15 | comp2.Add(&Leaf{name: "Leaf XYA"}) 16 | comp2.Add(&Leaf{name: "Leaf XYB"}) 17 | 18 | comp.Add(comp2) 19 | 20 | root.Add(&Leaf{name: "Leaf C"}) 21 | 22 | leaf := &Leaf{name: "Leaf D"} 23 | root.Add(leaf) 24 | root.Remove(leaf) 25 | 26 | root.Display(1) 27 | 28 | // OutPut: 29 | // -root 30 | // ---Leaf A 31 | // ---Leaf B 32 | // ---Composite X 33 | // -----Leaf XA 34 | // -----Leaf XB 35 | // -----Composite XY 36 | // -------Leaf XYA 37 | // -------Leaf XYB 38 | // ---Leaf C 39 | } 40 | -------------------------------------------------------------------------------- /19_组合模式/19.5_公司管理系统/composite.go: -------------------------------------------------------------------------------- 1 | package composite 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | //Company 公司接口 9 | type Company interface { 10 | Add(c Company) //增加 11 | Remove(c Company) //移除 12 | Display(depth int) //显示 13 | LineOfDuty() //履行职责 14 | } 15 | 16 | //ConcreteCompany 具体公司 17 | type ConcreteCompany struct { 18 | children []Company 19 | name string 20 | } 21 | 22 | //Add 添加公司 23 | func (con *ConcreteCompany) Add(c Company) { 24 | con.children = append(con.children, c) 25 | } 26 | 27 | //Remove 移除公司 28 | func (con *ConcreteCompany) Remove(c Company) { 29 | for index, val := range con.children { 30 | if val == c { 31 | con.children = append(con.children[0:index], con.children[index+1:]...) 32 | break 33 | } 34 | } 35 | } 36 | 37 | //Display 展示 38 | func (con *ConcreteCompany) Display(depth int) { 39 | fmt.Println(strings.Repeat("-", depth) + con.name) 40 | for _, component := range con.children { 41 | component.Display(depth + 2) 42 | } 43 | } 44 | 45 | //LineOfDuty 履行职责 46 | func (con *ConcreteCompany) LineOfDuty() { 47 | for _, component := range con.children { 48 | component.LineOfDuty() 49 | } 50 | } 51 | 52 | //HRDepartment 人力资源部 53 | type HRDepartment struct { 54 | name string 55 | } 56 | 57 | //Add 添加公司 58 | func (*HRDepartment) Add(c Company) { 59 | } 60 | 61 | //Remove 移除公司 62 | func (*HRDepartment) Remove(c Company) { 63 | } 64 | 65 | //Display 展示 66 | func (h *HRDepartment) Display(depth int) { 67 | fmt.Println(strings.Repeat("-", depth) + h.name) 68 | } 69 | 70 | //LineOfDuty 履行职责 71 | func (h *HRDepartment) LineOfDuty() { 72 | fmt.Printf("%s 员工招聘培训管理\n", h.name) 73 | } 74 | 75 | //FinanceDepartment 财务部 76 | type FinanceDepartment struct { 77 | name string 78 | } 79 | 80 | //Add 添加公司 81 | func (*FinanceDepartment) Add(c Company) { 82 | } 83 | 84 | //Remove 移除公司 85 | func (*FinanceDepartment) Remove(c Company) { 86 | } 87 | 88 | //Display 展示 89 | func (f *FinanceDepartment) Display(depth int) { 90 | fmt.Println(strings.Repeat("-", depth) + f.name) 91 | } 92 | 93 | //LineOfDuty 履行职责 94 | func (f *FinanceDepartment) LineOfDuty() { 95 | fmt.Printf("%s 公司财务收支管理\n", f.name) 96 | } 97 | -------------------------------------------------------------------------------- /19_组合模式/19.5_公司管理系统/composite_test.go: -------------------------------------------------------------------------------- 1 | package composite 2 | 3 | import "fmt" 4 | 5 | func ExampleComposite() { 6 | root := &ConcreteCompany{name: "北京总公司"} 7 | root.Add(&HRDepartment{name: "总公司人力资源部"}) 8 | root.Add(&FinanceDepartment{name: "总公司财务部"}) 9 | 10 | comp := &ConcreteCompany{name: "上海华东分公司"} 11 | comp.Add(&HRDepartment{name: "华东分公司人力资源部"}) 12 | comp.Add(&FinanceDepartment{name: "华东分公司财务部"}) 13 | root.Add(comp) 14 | 15 | comp1 := &ConcreteCompany{name: "南京办事处"} 16 | comp1.Add(&HRDepartment{name: "南京办事处人力资源部"}) 17 | comp1.Add(&FinanceDepartment{name: "南京办事处财务部"}) 18 | comp.Add(comp1) 19 | 20 | comp2 := &ConcreteCompany{name: "杭州办事处"} 21 | comp2.Add(&HRDepartment{name: "杭州办事处人力资源部"}) 22 | comp2.Add(&FinanceDepartment{name: "杭州办事处财务部"}) 23 | comp.Add(comp2) 24 | 25 | fmt.Println("结构图:") 26 | 27 | root.Display(1) 28 | 29 | fmt.Println("\n职责:") 30 | 31 | root.LineOfDuty() 32 | 33 | // OutPut: 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 | -------------------------------------------------------------------------------- /19_组合模式/README.md: -------------------------------------------------------------------------------- 1 | ### 组合模式 2 | 3 | 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 "组合对象" 的含义。 4 | 5 | 组合模式可以让客户端像修改配置文件一样简单的完成本来需要流程控制语句来完成的功能。 -------------------------------------------------------------------------------- /20_迭代器模式/README.md: -------------------------------------------------------------------------------- 1 | ### 迭代器模式(Iterator) 2 | 3 | 提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。 -------------------------------------------------------------------------------- /20_迭代器模式/iterator.go: -------------------------------------------------------------------------------- 1 | package iterator 2 | 3 | type Iterator interface { 4 | First() interface{} 5 | Next() interface{} 6 | IsDone() bool 7 | CurrentItem() interface{} 8 | } 9 | 10 | type ConcreteIterator struct { 11 | aggregate *ConcreteAggregate 12 | current int 13 | } 14 | 15 | func NewConcreteIterator(aggregate *ConcreteAggregate) *ConcreteIterator { 16 | return &ConcreteIterator{ 17 | aggregate: aggregate, 18 | current: 0, 19 | } 20 | } 21 | 22 | func (c *ConcreteIterator) First() interface{} { 23 | return c.aggregate.items[0] 24 | } 25 | 26 | func (c *ConcreteIterator) Next() interface{} { 27 | var ret interface{} 28 | c.current++ 29 | 30 | if c.current < len(c.aggregate.items) { 31 | ret = c.aggregate.items[c.current] 32 | } 33 | return ret 34 | } 35 | 36 | func (c *ConcreteIterator) CurrentItem() interface{} { 37 | return c.aggregate.items[c.current] 38 | } 39 | 40 | func (c *ConcreteIterator) IsDone() bool { 41 | if c.current >= len(c.aggregate.items) { 42 | return true 43 | } 44 | return false 45 | } 46 | 47 | type ConcreteIteratorDesc struct { 48 | aggregate *ConcreteAggregate 49 | current int 50 | } 51 | 52 | func NewConcreteIteratorDesc(aggregate *ConcreteAggregate) *ConcreteIteratorDesc { 53 | return &ConcreteIteratorDesc{ 54 | aggregate: aggregate, 55 | current: len(aggregate.items) - 1, 56 | } 57 | } 58 | 59 | func (c *ConcreteIteratorDesc) First() interface{} { 60 | return c.aggregate.items[len(c.aggregate.items)-1] 61 | } 62 | 63 | func (c *ConcreteIteratorDesc) Next() interface{} { 64 | var ret interface{} 65 | c.current-- 66 | if c.current >= 0 { 67 | ret = c.aggregate.items[c.current] 68 | } 69 | 70 | return ret 71 | } 72 | 73 | func (c *ConcreteIteratorDesc) CurrentItem() interface{} { 74 | return c.aggregate.items[c.current] 75 | } 76 | 77 | func (c *ConcreteIteratorDesc) IsDone() bool { 78 | if c.current < 0 { 79 | return true 80 | } 81 | return false 82 | } 83 | 84 | type Aggregate interface { 85 | CreateIterator() Iterator 86 | } 87 | 88 | type ConcreteAggregate struct { 89 | items []interface{} 90 | } 91 | 92 | func (c *ConcreteAggregate) CreateIterator() Iterator { 93 | return &ConcreteIterator{ 94 | aggregate: c, 95 | } 96 | } 97 | 98 | func (c *ConcreteAggregate) Count() int { 99 | return len(c.items) 100 | } 101 | -------------------------------------------------------------------------------- /20_迭代器模式/iterator_test.go: -------------------------------------------------------------------------------- 1 | package iterator 2 | 3 | import "fmt" 4 | 5 | func ExampleIterator() { 6 | a := &ConcreteAggregate{ 7 | items: make([]interface{}, 6), 8 | } 9 | 10 | a.items[0] = "大鸟" 11 | a.items[1] = "小菜" 12 | a.items[2] = "行李" 13 | a.items[3] = "老外" 14 | a.items[4] = "公交内部员工" 15 | a.items[5] = "小偷" 16 | 17 | i := NewConcreteIterator(a) 18 | 19 | for !i.IsDone() { 20 | fmt.Print(i.CurrentItem()) 21 | fmt.Println(" 请买车票!") 22 | i.Next() 23 | } 24 | 25 | // OutPut: 26 | // 大鸟 请买车票! 27 | // 小菜 请买车票! 28 | // 行李 请买车票! 29 | // 老外 请买车票! 30 | // 公交内部员工 请买车票! 31 | // 小偷 请买车票! 32 | 33 | } 34 | -------------------------------------------------------------------------------- /21_单例模式/README.md: -------------------------------------------------------------------------------- 1 | ### 单例模式(Singleton Pattern) 2 | 3 | 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。 -------------------------------------------------------------------------------- /21_单例模式/singleton.go: -------------------------------------------------------------------------------- 1 | package singleton 2 | 3 | import "sync" 4 | 5 | //Singleton 单例模式 6 | type Singleton struct{} 7 | 8 | var singleton *Singleton 9 | var once sync.Once 10 | 11 | //GetInstance 获取单例模式对象,双重检查加锁保证线程安全 12 | func GetInstance() *Singleton { 13 | once.Do(func() { 14 | singleton = new(Singleton) 15 | }) 16 | 17 | return singleton 18 | } 19 | -------------------------------------------------------------------------------- /21_单例模式/singleton_test.go: -------------------------------------------------------------------------------- 1 | package singleton 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | const parCount = 100 8 | 9 | func TestSingleton(t *testing.T) { 10 | ins1 := GetInstance() 11 | ins2 := GetInstance() 12 | if ins1 != ins2 { 13 | t.Fatal("singleton test fail") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /22_桥接模式/22.3_合成、聚合复用原则/README.md: -------------------------------------------------------------------------------- 1 | ### 合成/聚合复用原则 2 | 3 | 尽量使用合成/聚合,尽量不要使用类继承。 -------------------------------------------------------------------------------- /22_桥接模式/22.4_松耦合程序/bridge.go: -------------------------------------------------------------------------------- 1 | package bridge 2 | 3 | import "fmt" 4 | 5 | //HandsetSoft 手机软件 6 | type HandsetSoft interface { 7 | Run() 8 | } 9 | 10 | //HandsetAddressList 通讯录 11 | type HandsetAddressList interface { 12 | Run() 13 | } 14 | 15 | //HandsetGame 游戏 16 | type HandsetGame interface { 17 | Run() 18 | } 19 | 20 | //HandsetBrandMGame 手机品牌M的游戏 21 | type HandsetBrandMGame struct { 22 | } 23 | 24 | //Run 运行 25 | func (*HandsetBrandMGame) Run() { 26 | fmt.Println("运行M品牌手机游戏") 27 | } 28 | 29 | //HandsetBrandNGame 手机品牌N的游戏 30 | type HandsetBrandNGame struct { 31 | } 32 | 33 | //Run 运行 34 | func (*HandsetBrandNGame) Run() { 35 | fmt.Println("运行N品牌手机游戏") 36 | } 37 | 38 | //HandsetBrandMAddressList 手机品牌M的通讯录 39 | type HandsetBrandMAddressList struct { 40 | } 41 | 42 | //Run 运行 43 | func (*HandsetBrandMAddressList) Run() { 44 | fmt.Println("运行M品牌手机通讯录") 45 | } 46 | 47 | //HandsetBrandNAddressList 手机品牌N的通讯录 48 | type HandsetBrandNAddressList struct { 49 | } 50 | 51 | //Run 运行 52 | func (*HandsetBrandNAddressList) Run() { 53 | fmt.Println("运行N品牌手机通讯录") 54 | } 55 | -------------------------------------------------------------------------------- /22_桥接模式/22.4_松耦合程序/bridge_test.go: -------------------------------------------------------------------------------- 1 | package bridge 2 | 3 | func ExampleBridge() { 4 | var ab HandsetSoft 5 | ab = new(HandsetBrandMGame) 6 | ab.Run() 7 | 8 | ab = new(HandsetBrandNGame) 9 | ab.Run() 10 | 11 | ab = new(HandsetBrandMAddressList) 12 | ab.Run() 13 | 14 | ab = new(HandsetBrandNAddressList) 15 | ab.Run() 16 | 17 | // OutPut: 18 | // 运行M品牌手机游戏 19 | // 运行N品牌手机游戏 20 | // 运行M品牌手机通讯录 21 | // 运行N品牌手机通讯录 22 | 23 | } 24 | -------------------------------------------------------------------------------- /22_桥接模式/22.6_桥接模式(常规实现)/bridge.go: -------------------------------------------------------------------------------- 1 | package bridge 2 | 3 | import "fmt" 4 | 5 | type IAbstraction interface { 6 | Operation() 7 | } 8 | 9 | type Abstraction struct { 10 | implementor Implementor 11 | } 12 | 13 | func (a *Abstraction) SetImplementor(i Implementor) { 14 | a.implementor = i 15 | } 16 | 17 | func (a *Abstraction) Operation() { 18 | a.implementor.Operation() 19 | } 20 | 21 | type RefinedAbstraction struct { 22 | Abstraction 23 | } 24 | 25 | func (r *RefinedAbstraction) Operation() { 26 | r.Abstraction.Operation() 27 | } 28 | 29 | type Implementor interface { 30 | Operation() 31 | } 32 | 33 | type ConcreteImplementorA struct { 34 | } 35 | 36 | func (*ConcreteImplementorA) Operation() { 37 | fmt.Println("具体实现A的方法执行") 38 | } 39 | 40 | type ConcreteImplementorB struct { 41 | } 42 | 43 | func (*ConcreteImplementorB) Operation() { 44 | fmt.Println("具体实现B的方法执行") 45 | } 46 | -------------------------------------------------------------------------------- /22_桥接模式/22.6_桥接模式(常规实现)/bridge_test.go: -------------------------------------------------------------------------------- 1 | package bridge 2 | 3 | func ExampleBridge() { 4 | ab := new(RefinedAbstraction) 5 | 6 | ab.SetImplementor(new(ConcreteImplementorA)) 7 | ab.Operation() 8 | 9 | ab.SetImplementor(new(ConcreteImplementorB)) 10 | ab.Operation() 11 | 12 | // OutPut: 13 | // 具体实现A的方法执行 14 | // 具体实现B的方法执行 15 | } 16 | -------------------------------------------------------------------------------- /22_桥接模式/README.md: -------------------------------------------------------------------------------- 1 | ### 桥接模式(Bridge Pattern): 2 | 3 | 将抽象部分与它的实现部分分离,使它们都可以独立地变化。 -------------------------------------------------------------------------------- /23_命令模式/23.4_松耦合设计/command.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "fmt" 4 | 5 | //ICommand 命令接口 6 | type ICommand interface { 7 | //执行命令 8 | ExcuteCommand() 9 | } 10 | 11 | //BakeMuttonCommand 烤羊肉串命令 12 | type BakeMuttonCommand struct { 13 | receiver *Barbecuer 14 | } 15 | 16 | func NewBakeMuttonCommand(c *Barbecuer) *BakeMuttonCommand { 17 | return &BakeMuttonCommand{ 18 | receiver: c, 19 | } 20 | } 21 | 22 | func (b *BakeMuttonCommand) ExcuteCommand() { 23 | b.receiver.BakeMutton() 24 | } 25 | 26 | //BakeChickenWingCommand 烤鸡翅命令 27 | type BakeChickenWingCommand struct { 28 | receiver *Barbecuer 29 | } 30 | 31 | func NewBakeChickenWingCommand(c *Barbecuer) *BakeChickenWingCommand { 32 | return &BakeChickenWingCommand{ 33 | receiver: c, 34 | } 35 | } 36 | 37 | func (b *BakeChickenWingCommand) ExcuteCommand() { 38 | b.receiver.BakeChickenWing() 39 | } 40 | 41 | //Barbecuer 烤肉串者 42 | type Barbecuer struct { 43 | } 44 | 45 | func (*Barbecuer) BakeMutton() { 46 | fmt.Println("烤羊肉串!") 47 | } 48 | 49 | func (*Barbecuer) BakeChickenWing() { 50 | fmt.Println("烤鸡翅!") 51 | } 52 | 53 | //Waiter 服务员 54 | type Waiter struct { 55 | command ICommand 56 | } 57 | 58 | //SetOrder 设置订单 59 | func (w *Waiter) SetOrder(command ICommand) { 60 | w.command = command 61 | } 62 | 63 | //Notify 通知执行 64 | func (w *Waiter) Notify() { 65 | w.command.ExcuteCommand() 66 | } 67 | -------------------------------------------------------------------------------- /23_命令模式/23.4_松耦合设计/command_test.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | func ExampleCommand() { 4 | //开店前的准备 5 | boy := new(Barbecuer) 6 | bakeMuttonCommand1 := NewBakeMuttonCommand(boy) 7 | bakeMuttonCommand2 := NewBakeMuttonCommand(boy) 8 | bakeChickenWingCommand1 := NewBakeChickenWingCommand(boy) 9 | girl := new(Waiter) 10 | 11 | //开门营业 12 | girl.SetOrder(bakeMuttonCommand1) 13 | girl.Notify() 14 | girl.SetOrder(bakeMuttonCommand2) 15 | girl.Notify() 16 | girl.SetOrder(bakeChickenWingCommand1) 17 | girl.Notify() 18 | 19 | // OutPut: 20 | // 烤羊肉串! 21 | // 烤羊肉串! 22 | // 烤鸡翅! 23 | } 24 | -------------------------------------------------------------------------------- /23_命令模式/23.5_松耦合后/command.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "fmt" 4 | 5 | //ICommand 命令接口 6 | type ICommand interface { 7 | //执行命令 8 | ExcuteCommand() 9 | } 10 | 11 | //BakeMuttonCommand 烤羊肉串命令 12 | type BakeMuttonCommand struct { 13 | receiver *Barbecuer 14 | } 15 | 16 | func NewBakeMuttonCommand(c *Barbecuer) *BakeMuttonCommand { 17 | return &BakeMuttonCommand{ 18 | receiver: c, 19 | } 20 | } 21 | 22 | func (b *BakeMuttonCommand) ExcuteCommand() { 23 | b.receiver.BakeMutton() 24 | } 25 | 26 | //BakeChickenWingCommand 烤鸡翅命令 27 | type BakeChickenWingCommand struct { 28 | receiver *Barbecuer 29 | } 30 | 31 | func NewBakeChickenWingCommand(c *Barbecuer) *BakeChickenWingCommand { 32 | return &BakeChickenWingCommand{ 33 | receiver: c, 34 | } 35 | } 36 | 37 | func (b *BakeChickenWingCommand) ExcuteCommand() { 38 | b.receiver.BakeChickenWing() 39 | } 40 | 41 | //Barbecuer 烤肉串者 42 | type Barbecuer struct { 43 | } 44 | 45 | func (*Barbecuer) BakeMutton() { 46 | fmt.Println("烤羊肉串!") 47 | } 48 | 49 | func (*Barbecuer) BakeChickenWing() { 50 | fmt.Println("烤鸡翅!") 51 | } 52 | 53 | //Waiter 服务员 54 | type Waiter struct { 55 | orders []ICommand 56 | } 57 | 58 | //SetOrder 设置订单 59 | func (w *Waiter) SetOrder(command ICommand) { 60 | w.orders = append(w.orders, command) 61 | } 62 | 63 | //CancelOrder 取消订单 64 | func (w *Waiter) CancelOrder(command ICommand) { 65 | for index, val := range w.orders { 66 | if val == command { 67 | w.orders = append(w.orders[:index], w.orders[index+1:]...) 68 | break 69 | } 70 | } 71 | } 72 | 73 | //Notify 通知执行 74 | func (w *Waiter) Notify() { 75 | for _, command := range w.orders { 76 | command.ExcuteCommand() 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /23_命令模式/23.5_松耦合后/command_test.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | func ExampleCommand() { 4 | //开店前的准备 5 | boy := new(Barbecuer) 6 | bakeMuttonCommand1 := NewBakeMuttonCommand(boy) 7 | bakeMuttonCommand2 := NewBakeMuttonCommand(boy) 8 | bakeChickenWingCommand1 := NewBakeChickenWingCommand(boy) 9 | girl := new(Waiter) 10 | 11 | //开门营业 12 | girl.SetOrder(bakeMuttonCommand1) 13 | girl.SetOrder(bakeMuttonCommand2) 14 | girl.SetOrder(bakeChickenWingCommand1) 15 | 16 | girl.Notify() 17 | 18 | // OutPut: 19 | // 烤羊肉串! 20 | // 烤羊肉串! 21 | // 烤鸡翅! 22 | } 23 | -------------------------------------------------------------------------------- /23_命令模式/23.6_命令模式(常规实现)/command.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "fmt" 4 | 5 | type ICommand interface { 6 | Execute() 7 | } 8 | 9 | type ConcreteCommand struct { 10 | receiver *Receiver 11 | } 12 | 13 | func NewConcreteCommand(receiver *Receiver) *ConcreteCommand { 14 | return &ConcreteCommand{ 15 | receiver: receiver, 16 | } 17 | } 18 | 19 | func (c *ConcreteCommand) Execute() { 20 | c.receiver.Action() 21 | } 22 | 23 | type Receiver struct { 24 | } 25 | 26 | func (*Receiver) Action() { 27 | fmt.Println("执行请求!") 28 | } 29 | 30 | type Invoker struct { 31 | command ICommand 32 | } 33 | 34 | func (i *Invoker) SetCommand(command ICommand) { 35 | i.command = command 36 | } 37 | 38 | func (i *Invoker) ExecuteCommand() { 39 | i.command.Execute() 40 | } 41 | -------------------------------------------------------------------------------- /23_命令模式/23.6_命令模式(常规实现)/command_test.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | func ExampleCommand() { 4 | r := new(Receiver) 5 | c := NewConcreteCommand(r) 6 | i := new(Invoker) 7 | 8 | // Set and execute command 9 | i.SetCommand(c) 10 | i.ExecuteCommand() 11 | 12 | // OutPut: 13 | // 执行请求! 14 | } 15 | -------------------------------------------------------------------------------- /23_命令模式/README.md: -------------------------------------------------------------------------------- 1 | ### 命令模式(Command Pattern) 2 | 3 | 将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。 -------------------------------------------------------------------------------- /24_职责链模式/24.3_职责链模式(常规实现)/chain_of_responsibility.go: -------------------------------------------------------------------------------- 1 | package chain 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | type IHandler interface { 9 | HandleRequest(request int) 10 | } 11 | 12 | type Handler struct { 13 | IHandler 14 | successor *Handler 15 | } 16 | 17 | func (h *Handler) HandleRequest(request int) { 18 | h.IHandler.HandleRequest(request) 19 | if h.successor != nil { 20 | h.successor.HandleRequest(request) 21 | } 22 | } 23 | 24 | func (h *Handler) SetSuccessor(s *Handler) { 25 | h.successor = s 26 | } 27 | 28 | type ConcreteHandler1 struct { 29 | } 30 | 31 | func NewConcreteHandler1() *Handler { 32 | return &Handler{ 33 | IHandler: new(ConcreteHandler1), 34 | } 35 | } 36 | 37 | func (c *ConcreteHandler1) HandleRequest(request int) { 38 | if request >= 0 && request < 10 { 39 | fmt.Printf("%s 处理请求 %d\n", reflect.TypeOf(c).Elem().Name(), request) 40 | } 41 | } 42 | 43 | type ConcreteHandler2 struct { 44 | } 45 | 46 | func NewConcreteHandler2() *Handler { 47 | return &Handler{ 48 | IHandler: new(ConcreteHandler2), 49 | } 50 | } 51 | 52 | func (c *ConcreteHandler2) HandleRequest(request int) { 53 | if request >= 10 && request < 20 { 54 | fmt.Printf("%s 处理请求 %d\n", reflect.TypeOf(c).Elem().Name(), request) 55 | } 56 | } 57 | 58 | type ConcreteHandler3 struct { 59 | } 60 | 61 | func NewConcreteHandler3() *Handler { 62 | return &Handler{ 63 | IHandler: new(ConcreteHandler3), 64 | } 65 | } 66 | 67 | func (c *ConcreteHandler3) HandleRequest(request int) { 68 | if request >= 20 && request < 30 { 69 | fmt.Printf("%s 处理请求 %d\n", reflect.TypeOf(c).Elem().Name(), request) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /24_职责链模式/24.3_职责链模式(常规实现)/chain_of_responsibility_test.go: -------------------------------------------------------------------------------- 1 | package chain 2 | 3 | func ExampleChain() { 4 | h1 := NewConcreteHandler1() 5 | h2 := NewConcreteHandler2() 6 | h3 := NewConcreteHandler3() 7 | h1.SetSuccessor(h2) 8 | h2.SetSuccessor(h3) 9 | 10 | requests := []int{2, 5, 14, 22, 18, 3, 27, 20} 11 | for _, val := range requests { 12 | h1.HandleRequest(val) 13 | } 14 | 15 | // OutPut: 16 | // ConcreteHandler1 处理请求 2 17 | // ConcreteHandler1 处理请求 5 18 | // ConcreteHandler2 处理请求 14 19 | // ConcreteHandler3 处理请求 22 20 | // ConcreteHandler2 处理请求 18 21 | // ConcreteHandler1 处理请求 3 22 | // ConcreteHandler3 处理请求 27 23 | // ConcreteHandler3 处理请求 20 24 | } 25 | -------------------------------------------------------------------------------- /24_职责链模式/README.md: -------------------------------------------------------------------------------- 1 | ### 职责链模式 2 | 3 | 很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。 -------------------------------------------------------------------------------- /25_中介者模式/25.2_中介者模式(常规实现)/mediator.go: -------------------------------------------------------------------------------- 1 | package mediator 2 | 3 | import "fmt" 4 | 5 | //Mediator 中介者接口 6 | type Mediator interface { 7 | Send(message string, colleague Colleague) 8 | } 9 | 10 | //ConcreteMediator 具体中介者 11 | type ConcreteMediator struct { 12 | Colleague1 *ConcreteColleague1 13 | Colleague2 *ConcreteColleague2 14 | } 15 | 16 | //Send 中介者转发消息 17 | func (c *ConcreteMediator) Send(message string, colleague Colleague) { 18 | if colleague == c.Colleague1 { 19 | c.Colleague2.Notify(message) 20 | } else { 21 | c.Colleague1.Notify(message) 22 | } 23 | } 24 | 25 | //Colleague 消息接收者 26 | type Colleague interface { 27 | Send(message string) 28 | Notify(message string) 29 | } 30 | 31 | //ConcreteColleague1 同事1 32 | type ConcreteColleague1 struct { 33 | mediator Mediator 34 | } 35 | 36 | //NewConcreteColleague1 同事1构造函数 37 | func NewConcreteColleague1(mediator Mediator) *ConcreteColleague1 { 38 | return &ConcreteColleague1{ 39 | mediator: mediator, 40 | } 41 | } 42 | 43 | //Send 发消息 44 | func (c *ConcreteColleague1) Send(message string) { 45 | c.mediator.Send(message, c) 46 | } 47 | 48 | //Notify 通知 49 | func (c *ConcreteColleague1) Notify(message string) { 50 | fmt.Println("同事1得到信息:" + message) 51 | } 52 | 53 | //ConcreteColleague2 同事2 54 | type ConcreteColleague2 struct { 55 | mediator Mediator 56 | } 57 | 58 | //NewConcreteColleague2 同事2构造函数 59 | func NewConcreteColleague2(mediator Mediator) *ConcreteColleague2 { 60 | return &ConcreteColleague2{ 61 | mediator: mediator, 62 | } 63 | } 64 | 65 | //Send 发消息 66 | func (c *ConcreteColleague2) Send(message string) { 67 | c.mediator.Send(message, c) 68 | } 69 | 70 | //Notify 通知 71 | func (c *ConcreteColleague2) Notify(message string) { 72 | fmt.Println("同事2得到信息:" + message) 73 | } 74 | -------------------------------------------------------------------------------- /25_中介者模式/25.2_中介者模式(常规实现)/mediator_test.go: -------------------------------------------------------------------------------- 1 | package mediator 2 | 3 | func ExampleMediator() { 4 | m := new(ConcreteMediator) 5 | 6 | c1 := NewConcreteColleague1(m) 7 | c2 := NewConcreteColleague2(m) 8 | 9 | m.Colleague1 = c1 10 | m.Colleague2 = c2 11 | 12 | c1.Send("吃过饭了吗?") 13 | c2.Send("没有呢,你打算请客?") 14 | 15 | // OutPut: 16 | // 同事2得到信息:吃过饭了吗? 17 | // 同事1得到信息:没有呢,你打算请客? 18 | } 19 | -------------------------------------------------------------------------------- /25_中介者模式/25.3_安理会做中介/mediator.go: -------------------------------------------------------------------------------- 1 | package mediator 2 | 3 | import "fmt" 4 | 5 | //UnitedNations 联合国机构 6 | type UnitedNations interface { 7 | Declare(message string, colleague Country) 8 | } 9 | 10 | //UnitedNationsSecurityCouncil 联合国安全理事会 11 | type UnitedNationsSecurityCouncil struct { 12 | Colleague1 *USA 13 | Colleague2 *Iraq 14 | } 15 | 16 | //Declare 声明 17 | func (u *UnitedNationsSecurityCouncil) Declare(message string, colleague Country) { 18 | if colleague == u.Colleague1 { 19 | u.Colleague2.GetMessage(message) 20 | } else { 21 | u.Colleague1.GetMessage(message) 22 | } 23 | } 24 | 25 | //Country 国家 26 | type Country interface { 27 | Declare(message string) 28 | GetMessage(message string) 29 | } 30 | 31 | //USA 美国 32 | type USA struct { 33 | mediator UnitedNations 34 | } 35 | 36 | //NewUSA 美国构造函数 37 | func NewUSA(mediator UnitedNations) *USA { 38 | return &USA{ 39 | mediator: mediator, 40 | } 41 | } 42 | 43 | //Declare 声明 44 | func (u *USA) Declare(message string) { 45 | u.mediator.Declare(message, u) 46 | } 47 | 48 | //GetMessage 获得消息 49 | func (u *USA) GetMessage(message string) { 50 | fmt.Println("美国获得对方信息:" + message) 51 | } 52 | 53 | //Iraq 伊拉克 54 | type Iraq struct { 55 | mediator UnitedNations 56 | } 57 | 58 | //NewIraq 伊拉克构造函数 59 | func NewIraq(mediator UnitedNations) *Iraq { 60 | return &Iraq{ 61 | mediator: mediator, 62 | } 63 | } 64 | 65 | //Declare 声明 66 | func (i *Iraq) Declare(message string) { 67 | i.mediator.Declare(message, i) 68 | } 69 | 70 | //GetMessage 获得消息 71 | func (i *Iraq) GetMessage(message string) { 72 | fmt.Println("伊拉克获得对方信息:" + message) 73 | } 74 | -------------------------------------------------------------------------------- /25_中介者模式/25.3_安理会做中介/mediator_test.go: -------------------------------------------------------------------------------- 1 | package mediator 2 | 3 | func ExampleMediator() { 4 | UNSC := new(UnitedNationsSecurityCouncil) 5 | 6 | c1 := NewUSA(UNSC) 7 | c2 := NewIraq(UNSC) 8 | 9 | UNSC.Colleague1 = c1 10 | UNSC.Colleague2 = c2 11 | 12 | c1.Declare("不准研制核武器,否则要发动战争!") 13 | c2.Declare("我们没有核武器,也不怕侵略。") 14 | 15 | // OutPut: 16 | // 伊拉克获得对方信息:不准研制核武器,否则要发动战争! 17 | // 美国获得对方信息:我们没有核武器,也不怕侵略。 18 | } 19 | -------------------------------------------------------------------------------- /25_中介者模式/README.md: -------------------------------------------------------------------------------- 1 | ### 中介者模式(Mediator Pattern) 2 | 3 | 用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 -------------------------------------------------------------------------------- /26_享元模式/26.2_享元模式常规实现/flyweight.go: -------------------------------------------------------------------------------- 1 | package flyweight 2 | 3 | import "fmt" 4 | 5 | //Flyweight 接口 6 | type Flyweight interface { 7 | Operation(extrinsicstate int) 8 | } 9 | 10 | //ConcreteFlyweight 具体对象 11 | type ConcreteFlyweight struct { 12 | } 13 | 14 | //Operation 操作 15 | func (*ConcreteFlyweight) Operation(extrinsicstate int) { 16 | fmt.Printf("具体Flyweight:%d\n", extrinsicstate) 17 | } 18 | 19 | //UnsharedConcreteFlyweight 非共享对象 20 | type UnsharedConcreteFlyweight struct { 21 | } 22 | 23 | //Operation 操作 24 | func (*UnsharedConcreteFlyweight) Operation(extrinsicstate int) { 25 | fmt.Printf("不共享的具体Flyweight:%d\n", extrinsicstate) 26 | } 27 | 28 | //FlyweightFactory 共享对象工厂 29 | type FlyweightFactory struct { 30 | flyweights map[string]*ConcreteFlyweight 31 | } 32 | 33 | //NewFlyweightFactory 对象工厂 34 | func NewFlyweightFactory() *FlyweightFactory { 35 | f := &FlyweightFactory{ 36 | flyweights: make(map[string]*ConcreteFlyweight), 37 | } 38 | f.flyweights["x"] = new(ConcreteFlyweight) 39 | f.flyweights["y"] = new(ConcreteFlyweight) 40 | f.flyweights["z"] = new(ConcreteFlyweight) 41 | return f 42 | } 43 | 44 | //GetFlyweight 获取共享对象 45 | func (f *FlyweightFactory) GetFlyweight(key string) Flyweight { 46 | return Flyweight(f.flyweights[key]) 47 | } 48 | -------------------------------------------------------------------------------- /26_享元模式/26.2_享元模式常规实现/flyweight_test.go: -------------------------------------------------------------------------------- 1 | package flyweight 2 | 3 | func ExampleFlyweight() { 4 | extrinsicstate := 22 5 | 6 | f := NewFlyweightFactory() 7 | 8 | fx := f.GetFlyweight("X") 9 | extrinsicstate-- 10 | fx.Operation(extrinsicstate) 11 | 12 | fy := f.GetFlyweight("Y") 13 | extrinsicstate-- 14 | fy.Operation(extrinsicstate) 15 | 16 | fz := f.GetFlyweight("Z") 17 | extrinsicstate-- 18 | fz.Operation(extrinsicstate) 19 | 20 | uf := new(UnsharedConcreteFlyweight) 21 | extrinsicstate-- 22 | uf.Operation(extrinsicstate) 23 | 24 | // OutPut: 25 | // 具体Flyweight:21 26 | // 具体Flyweight:20 27 | // 具体Flyweight:19 28 | // 不共享的具体Flyweight:18 29 | 30 | } 31 | -------------------------------------------------------------------------------- /26_享元模式/26.3_网站共享代码/flyweight.go: -------------------------------------------------------------------------------- 1 | package flyweight 2 | 3 | import "fmt" 4 | 5 | //WebSite 网站 6 | type WebSite interface { 7 | Use() 8 | } 9 | 10 | //ConcreteWebSite 具体的网站 11 | type ConcreteWebSite struct { 12 | Name string 13 | } 14 | 15 | //Use 使用 16 | func (c *ConcreteWebSite) Use() { 17 | fmt.Println("网站分类:" + c.Name) 18 | } 19 | 20 | //WebSiteFactory 网站工厂 21 | type WebSiteFactory struct { 22 | flyweights map[string]*ConcreteWebSite 23 | } 24 | 25 | //GetWebSiteCategory 获得网站分类 26 | func (w *WebSiteFactory) GetWebSiteCategory(key string) WebSite { 27 | c := new(ConcreteWebSite) 28 | c.Name = key 29 | w.flyweights[key] = c 30 | return WebSite(w.flyweights[key]) 31 | } 32 | 33 | //GetWebSiteCount 获得网站分类总数 34 | func (w *WebSiteFactory) GetWebSiteCount() int { 35 | return len(w.flyweights) 36 | } 37 | -------------------------------------------------------------------------------- /26_享元模式/26.3_网站共享代码/flyweight_test.go: -------------------------------------------------------------------------------- 1 | package flyweight 2 | 3 | import "fmt" 4 | 5 | func ExampleFlyweight() { 6 | f := &WebSiteFactory{ 7 | flyweights: make(map[string]*ConcreteWebSite), 8 | } 9 | 10 | fx := f.GetWebSiteCategory("产品展示") 11 | fx.Use() 12 | 13 | fy := f.GetWebSiteCategory("产品展示") 14 | fy.Use() 15 | 16 | fz := f.GetWebSiteCategory("产品展示") 17 | fz.Use() 18 | 19 | fl := f.GetWebSiteCategory("博客") 20 | fl.Use() 21 | 22 | fm := f.GetWebSiteCategory("博客") 23 | fm.Use() 24 | 25 | fn := f.GetWebSiteCategory("博客") 26 | fn.Use() 27 | 28 | fmt.Printf("网站分类总数为 %d", f.GetWebSiteCount()) 29 | 30 | // OutPut: 31 | // 网站分类:产品展示 32 | // 网站分类:产品展示 33 | // 网站分类:产品展示 34 | // 网站分类:博客 35 | // 网站分类:博客 36 | // 网站分类:博客 37 | // 网站分类总数为 2 38 | 39 | } 40 | -------------------------------------------------------------------------------- /26_享元模式/README.md: -------------------------------------------------------------------------------- 1 | ### 享元模式(Flyweight Pattern) 2 | 3 | 运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式。 -------------------------------------------------------------------------------- /27_解析器模式/27.2_解析器模式(常规实现)/interpreter.go: -------------------------------------------------------------------------------- 1 | package interpreter 2 | 3 | import "fmt" 4 | 5 | //Context 上下文 6 | type Context struct { 7 | Input string 8 | Output string 9 | } 10 | 11 | //AbstractExpression 解析器接口 12 | type AbstractExpression interface { 13 | Interpret(context *Context) 14 | } 15 | 16 | //TerminalExpression 终端解释器 17 | type TerminalExpression struct { 18 | } 19 | 20 | //Interpret 解析操作 21 | func (*TerminalExpression) Interpret(context *Context) { 22 | fmt.Println("终端解释器") 23 | } 24 | 25 | //NonterminalExpression 非终端解释器 26 | type NonterminalExpression struct { 27 | } 28 | 29 | //Interpret 解析操作 30 | func (*NonterminalExpression) Interpret(context *Context) { 31 | fmt.Println("非终端解释器") 32 | } 33 | -------------------------------------------------------------------------------- /27_解析器模式/27.2_解析器模式(常规实现)/interpreter_test.go: -------------------------------------------------------------------------------- 1 | package interpreter 2 | 3 | func ExampleInterpreter() { 4 | context := new(Context) 5 | list := make([]AbstractExpression, 0, 4) 6 | list = append(list, new(TerminalExpression)) 7 | list = append(list, new(NonterminalExpression)) 8 | list = append(list, new(TerminalExpression)) 9 | list = append(list, new(TerminalExpression)) 10 | 11 | for _, exp := range list { 12 | exp.Interpret(context) 13 | } 14 | 15 | // OutPut: 16 | // 终端解释器 17 | // 非终端解释器 18 | // 终端解释器 19 | // 终端解释器 20 | 21 | } 22 | -------------------------------------------------------------------------------- /27_解析器模式/README.md: -------------------------------------------------------------------------------- 1 | ### 解释器(Interpreter) 2 | 3 | 给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。 -------------------------------------------------------------------------------- /28_访问者模式/28.3_简单的面向对象设计/visitor.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | //Person 人类 9 | type Person interface { 10 | GetConclusion() 11 | } 12 | 13 | //Man 男人 14 | type Man struct { 15 | Action string 16 | } 17 | 18 | //GetConclusion 得到结论或反应 19 | func (m *Man) GetConclusion() { 20 | if m.Action == "成功" { 21 | fmt.Printf("%s%s时,背后多半有一个伟大的女人。\n", reflect.TypeOf(m).Elem().Name(), m.Action) 22 | } else if m.Action == "失败" { 23 | fmt.Printf("%s%s时,闷头喝酒,谁也不用劝。\n", reflect.TypeOf(m).Elem().Name(), m.Action) 24 | } else if m.Action == "恋爱" { 25 | fmt.Printf("%s%s时,凡事不懂也要装懂。\n", reflect.TypeOf(m).Elem().Name(), m.Action) 26 | } 27 | } 28 | 29 | //Woman 女人 30 | type Woman struct { 31 | Action string 32 | } 33 | 34 | //GetConclusion 得到结论或反应 35 | func (w *Woman) GetConclusion() { 36 | if w.Action == "成功" { 37 | fmt.Printf("%s%s时,背后大多有一个不成功的男人。\n", reflect.TypeOf(w).Elem().Name(), w.Action) 38 | } else if w.Action == "失败" { 39 | fmt.Printf("%s%s时,眼泪汪汪,谁也劝不了。\n", reflect.TypeOf(w).Elem().Name(), w.Action) 40 | } else if w.Action == "恋爱" { 41 | fmt.Printf("%s%s时,遇事懂也装作不懂。\n", reflect.TypeOf(w).Elem().Name(), w.Action) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /28_访问者模式/28.3_简单的面向对象设计/visitor_test.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | func ExampleVisitor() { 4 | persons := make([]Person, 0) 5 | 6 | man1 := new(Man) 7 | man1.Action = "成功" 8 | persons = append(persons, man1) 9 | 10 | woman1 := new(Woman) 11 | woman1.Action = "成功" 12 | persons = append(persons, woman1) 13 | 14 | man2 := new(Man) 15 | man2.Action = "失败" 16 | persons = append(persons, man2) 17 | 18 | woman2 := new(Woman) 19 | woman2.Action = "失败" 20 | persons = append(persons, woman2) 21 | 22 | man3 := new(Man) 23 | man3.Action = "恋爱" 24 | persons = append(persons, man3) 25 | 26 | woman3 := new(Woman) 27 | woman3.Action = "恋爱" 28 | persons = append(persons, woman3) 29 | 30 | for _, item := range persons { 31 | item.GetConclusion() 32 | } 33 | 34 | // OutPut: 35 | // Man成功时,背后多半有一个伟大的女人。 36 | // Woman成功时,背后大多有一个不成功的男人。 37 | // Man失败时,闷头喝酒,谁也不用劝。 38 | // Woman失败时,眼泪汪汪,谁也劝不了。 39 | // Man恋爱时,凡事不懂也要装懂。 40 | // Woman恋爱时,遇事懂也装作不懂。 41 | } 42 | -------------------------------------------------------------------------------- /28_访问者模式/28.4_用模式实现/visitor.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | //Action 接口 9 | type Action interface { 10 | //得到男人结论或反应 11 | GetManConclusion(concreteElementA *Man) 12 | //得到女人结论或反应 13 | GetWomanConclusion(concreteElementB *Woman) 14 | } 15 | 16 | //Success 成功 17 | type Success struct { 18 | } 19 | 20 | //GetManConclusion 得到男人结论或反应 21 | func (s *Success) GetManConclusion(concreteElementA *Man) { 22 | fmt.Printf("%s%s时,背后多半有一个伟大的女人。\n", reflect.TypeOf(concreteElementA).Elem().Name(), reflect.TypeOf(s).Elem().Name()) 23 | } 24 | 25 | //GetWomanConclusion 得到女人结论或反应 26 | func (s *Success) GetWomanConclusion(concreteElementB *Woman) { 27 | fmt.Printf("%s%s时,背后大多有一个不成功的男人。\n", reflect.TypeOf(concreteElementB).Elem().Name(), reflect.TypeOf(s).Elem().Name()) 28 | } 29 | 30 | //Failing 失败 31 | type Failing struct { 32 | } 33 | 34 | //GetManConclusion 得到男人结论或反应 35 | func (f *Failing) GetManConclusion(concreteElementA *Man) { 36 | fmt.Printf("%s%s时,闷头喝酒,谁也不用劝。\n", reflect.TypeOf(concreteElementA).Elem().Name(), reflect.TypeOf(f).Elem().Name()) 37 | } 38 | 39 | //GetWomanConclusion 得到女人结论或反应 40 | func (f *Failing) GetWomanConclusion(concreteElementB *Woman) { 41 | fmt.Printf("%s%s时,眼泪汪汪,谁也劝不了。\n", reflect.TypeOf(concreteElementB).Elem().Name(), reflect.TypeOf(f).Elem().Name()) 42 | } 43 | 44 | //Amativeness 恋爱 45 | type Amativeness struct { 46 | } 47 | 48 | //GetManConclusion 得到男人结论或反应 49 | func (a *Amativeness) GetManConclusion(concreteElementA *Man) { 50 | fmt.Printf("%s%s时,凡事不懂也要装懂。\n", reflect.TypeOf(concreteElementA).Elem().Name(), reflect.TypeOf(a).Elem().Name()) 51 | } 52 | 53 | //GetWomanConclusion 得到女人结论或反应 54 | func (a *Amativeness) GetWomanConclusion(concreteElementB *Woman) { 55 | fmt.Printf("%s%s时,遇事懂也装作不懂\n", reflect.TypeOf(concreteElementB).Elem().Name(), reflect.TypeOf(a).Elem().Name()) 56 | } 57 | 58 | //Marriage 结婚 59 | type Marriage struct { 60 | } 61 | 62 | //GetManConclusion 得到男人结论或反应 63 | func (m *Marriage) GetManConclusion(concreteElementA *Man) { 64 | fmt.Printf("%s%s时,感慨道:恋爱游戏终结时,‘有妻徒刑’遥无期。\n", reflect.TypeOf(concreteElementA).Elem().Name(), reflect.TypeOf(m).Elem().Name()) 65 | } 66 | 67 | //GetWomanConclusion 得到女人结论或反应 68 | func (m *Marriage) GetWomanConclusion(concreteElementB *Woman) { 69 | fmt.Printf("%s%s时,欣慰曰:爱情长跑路漫漫,婚姻保险保平安。\n", reflect.TypeOf(concreteElementB).Elem().Name(), reflect.TypeOf(m).Elem().Name()) 70 | } 71 | 72 | //Person 人 73 | type Person interface { 74 | //接受 75 | Accept(visitor Action) 76 | } 77 | 78 | //Man 男人 79 | type Man struct { 80 | } 81 | 82 | //Accept 接受 83 | func (m *Man) Accept(visitor Action) { 84 | visitor.GetManConclusion(m) 85 | } 86 | 87 | //Woman 女人 88 | type Woman struct { 89 | } 90 | 91 | //Accept 接受 92 | func (w *Woman) Accept(visitor Action) { 93 | visitor.GetWomanConclusion(w) 94 | } 95 | 96 | //ObjectStructure 对象结构 97 | type ObjectStructure struct { 98 | elements []Person 99 | } 100 | 101 | //Attach 增加 102 | func (o *ObjectStructure) Attach(element Person) { 103 | o.elements = append(o.elements, element) 104 | } 105 | 106 | //Detach 移除 107 | func (o *ObjectStructure) Detach(element Person) { 108 | for index, val := range o.elements { 109 | if val == element { 110 | o.elements = append(o.elements[:index], o.elements[index+1:]...) 111 | break 112 | } 113 | } 114 | } 115 | 116 | //Display 查看显示 117 | func (o *ObjectStructure) Display(visitor Action) { 118 | for _, e := range o.elements { 119 | e.Accept(visitor) 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /28_访问者模式/28.4_用模式实现/visitor_test.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | func ExampleVisitor() { 4 | o := new(ObjectStructure) 5 | o.Attach(new(Man)) 6 | o.Attach(new(Woman)) 7 | 8 | v1 := new(Success) 9 | o.Display(v1) 10 | 11 | v2 := new(Failing) 12 | o.Display(v2) 13 | 14 | v3 := new(Amativeness) 15 | o.Display(v3) 16 | 17 | v4 := new(Marriage) 18 | o.Display(v4) 19 | 20 | // OutPut: 21 | // ManSuccess时,背后多半有一个伟大的女人。 22 | // WomanSuccess时,背后大多有一个不成功的男人。 23 | // ManFailing时,闷头喝酒,谁也不用劝。 24 | // WomanFailing时,眼泪汪汪,谁也劝不了。 25 | // ManAmativeness时,凡事不懂也要装懂。 26 | // WomanAmativeness时,遇事懂也装作不懂 27 | // ManMarriage时,感慨道:恋爱游戏终结时,‘有妻徒刑’遥无期。 28 | // WomanMarriage时,欣慰曰:爱情长跑路漫漫,婚姻保险保平安。 29 | } 30 | -------------------------------------------------------------------------------- /28_访问者模式/28.6_访问者模式(常规实现)/visitor.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | //Visitor 访问者接口 9 | type Visitor interface { 10 | VisitConcreteElementA(concreteElementA *ConcreteElementA) 11 | VisitConcreteElementB(concreteElementB *ConcreteElementB) 12 | } 13 | 14 | //ConcreteVisitor1 具体访问者 15 | type ConcreteVisitor1 struct { 16 | } 17 | 18 | //VisitConcreteElementA 访问节点 19 | func (v *ConcreteVisitor1) VisitConcreteElementA(concreteElementA *ConcreteElementA) { 20 | fmt.Printf("%s被%s访问\n", reflect.TypeOf(concreteElementA).Elem().Name(), reflect.TypeOf(v).Elem().Name()) 21 | } 22 | 23 | //VisitConcreteElementB 访问节点 24 | func (v *ConcreteVisitor1) VisitConcreteElementB(concreteElementB *ConcreteElementB) { 25 | fmt.Printf("%s被%s访问\n", reflect.TypeOf(concreteElementB).Elem().Name(), reflect.TypeOf(v).Elem().Name()) 26 | } 27 | 28 | //ConcreteVisitor2 具体访问者 29 | type ConcreteVisitor2 struct { 30 | } 31 | 32 | //VisitConcreteElementA 访问节点 33 | func (c *ConcreteVisitor2) VisitConcreteElementA(concreteElementA *ConcreteElementA) { 34 | fmt.Printf("%s被%s访问\n", reflect.TypeOf(concreteElementA).Elem().Name(), reflect.TypeOf(c).Elem().Name()) 35 | } 36 | 37 | //VisitConcreteElementB 访问节点 38 | func (c *ConcreteVisitor2) VisitConcreteElementB(concreteElementB *ConcreteElementB) { 39 | fmt.Printf("%s被%s访问\n", reflect.TypeOf(concreteElementB).Elem().Name(), reflect.TypeOf(c).Elem().Name()) 40 | } 41 | 42 | //Element 节点接口 43 | type Element interface { 44 | Accept(visitor Visitor) 45 | } 46 | 47 | //ConcreteElementA 具体节点 48 | type ConcreteElementA struct { 49 | } 50 | 51 | //Accept 接收函数 52 | func (c *ConcreteElementA) Accept(visitor Visitor) { 53 | visitor.VisitConcreteElementA(c) 54 | } 55 | 56 | func (c *ConcreteElementA) OperationA() {} 57 | 58 | type ConcreteElementB struct { 59 | } 60 | 61 | //Accept 接收函数 62 | func (c *ConcreteElementB) Accept(visitor Visitor) { 63 | visitor.VisitConcreteElementB(c) 64 | } 65 | 66 | func (c *ConcreteElementB) OperationB() { 67 | 68 | } 69 | 70 | //ObjectStructure 对象结构 71 | type ObjectStructure struct { 72 | elements []Element 73 | } 74 | 75 | //Attach 添加 76 | func (o *ObjectStructure) Attach(element Element) { 77 | o.elements = append(o.elements, element) 78 | } 79 | 80 | //Detach 移除 81 | func (o *ObjectStructure) Detach(element Element) { 82 | for index, val := range o.elements { 83 | if val == element { 84 | o.elements = append(o.elements[:index], o.elements[:index]...) 85 | break 86 | } 87 | } 88 | } 89 | 90 | //Accept 接收 91 | func (o *ObjectStructure) Accept(visitor Visitor) { 92 | for _, e := range o.elements { 93 | e.Accept(visitor) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /28_访问者模式/28.6_访问者模式(常规实现)/visitor_test.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | func ExampleVisitor() { 4 | o := new(ObjectStructure) 5 | o.Attach(new(ConcreteElementA)) 6 | o.Attach(new(ConcreteElementB)) 7 | 8 | v1 := new(ConcreteVisitor1) 9 | v2 := new(ConcreteVisitor2) 10 | 11 | o.Accept(v1) 12 | o.Accept(v2) 13 | 14 | // OutPut: 15 | // ConcreteElementA被ConcreteVisitor1访问 16 | // ConcreteElementB被ConcreteVisitor1访问 17 | // ConcreteElementA被ConcreteVisitor2访问 18 | // ConcreteElementB被ConcreteVisitor2访问 19 | } 20 | -------------------------------------------------------------------------------- /28_访问者模式/README.md: -------------------------------------------------------------------------------- 1 | ### 访问者模式(Visitor Pattern) 2 | 3 | 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 zhubingjian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 《大话设计模式》Go源码 2 | 3 | 《大话设计模式》Go实现,建议和书一起看 4 | 5 | 各模式README.md部分参考:https://github.com/me115/design_patterns -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module design-pattern-go 2 | 3 | go 1.13 4 | --------------------------------------------------------------------------------