简单工厂模式

    1. package main
    2. import "fmt"
    3. // ======= 抽象层 =========
    4. //水果类(抽象接口)
    5. type Fruit interface {
    6. Show() //接口的某方法
    7. }
    8. // ======= 基础类模块 =========
    9. type Apple struct {
    10. Fruit //为了易于理解显示继承(此行可以省略)
    11. }
    12. func (apple *Apple) Show() {
    13. fmt.Println("我是苹果")
    14. }
    15. type Banana struct {
    16. Fruit
    17. }
    18. func (banana *Banana) Show() {
    19. fmt.Println("我是香蕉")
    20. }
    21. type Pear struct {
    22. Fruit
    23. }
    24. func (pear *Pear) Show() {
    25. fmt.Println("我是梨")
    26. }
    27. // ========= 工厂模块 =========
    28. //一个工厂, 有一个生产水果的机器,返回一个抽象水果的指针
    29. type Factory struct {}
    30. func (fac *Factory) CreateFruit(kind string) Fruit {
    31. var fruit Fruit
    32. if kind == "apple" {
    33. fruit = new(Apple)
    34. } else if kind == "banana" {
    35. fruit = new(Banana)
    36. } else if kind == "pear" {
    37. fruit = new(Pear)
    38. }
    39. return fruit
    40. }
    41. // ==========业务逻辑层==============
    42. func main() {
    43. factory := new(Factory)
    44. apple := factory.CreateFruit("apple")
    45. apple.Show()
    46. banana := factory.CreateFruit("banana")
    47. banana.Show()
    48. pear := factory.CreateFruit("pear")
    49. pear.Show()
    50. }

    工厂方式

    1. package main
    2. import "fmt"
    3. // ======= 抽象层 =========
    4. //水果类(抽象接口)
    5. type Fruit interface {
    6. Show() //接口的某方法
    7. }
    8. //工厂类(抽象接口)
    9. type AbstractFactory interface {
    10. CreateFruit() Fruit //生产水果类(抽象)的生产器方法
    11. }
    12. // ======= 基础类模块 =========
    13. type Apple struct {
    14. Fruit //为了易于理解显示继承(此行可以省略)
    15. }
    16. func (apple *Apple) Show() {
    17. fmt.Println("我是苹果")
    18. }
    19. type Banana struct {
    20. Fruit
    21. }
    22. func (banana *Banana) Show() {
    23. fmt.Println("我是香蕉")
    24. }
    25. type Pear struct {
    26. Fruit
    27. }
    28. func (pear *Pear) Show() {
    29. fmt.Println("我是梨")
    30. }
    31. // ========= 工厂模块 =========
    32. //具体的苹果工厂
    33. type AppleFactory struct {
    34. AbstractFactory
    35. }
    36. func (fac *AppleFactory) CreateFruit() Fruit {
    37. var fruit Fruit
    38. //生产一个具体的苹果
    39. fruit = new(Apple)
    40. return fruit
    41. }
    42. //具体的香蕉工厂
    43. type BananaFactory struct {
    44. AbstractFactory
    45. }
    46. func (fac *BananaFactory) CreateFruit() Fruit {
    47. var fruit Fruit
    48. //生产一个具体的香蕉
    49. fruit = new(Banana)
    50. return fruit
    51. }
    52. //具体的梨工厂
    53. type PearFactory struct {
    54. AbstractFactory
    55. }
    56. func (fac *PearFactory) CreateFruit() Fruit {
    57. var fruit Fruit
    58. //生产一个具体的梨
    59. fruit = new(Pear)
    60. return fruit
    61. }
    62. //======= 业务逻辑层 =======
    63. func main() {
    64. /*
    65. 本案例为了突出根据依赖倒转原则与面向接口编程特性。
    66. 一些变量的定义将使用显示类型声明方式
    67. */
    68. //需求1:需要一个具体的苹果对象
    69. //1-先要一个具体的苹果工厂
    70. var appleFac AbstractFactory
    71. appleFac = new(AppleFactory)
    72. //2-生产相对应的具体水果
    73. var apple Fruit
    74. apple = appleFac.CreateFruit()
    75. apple.Show()
    76. //需求2:需要一个具体的香蕉对象
    77. //1-先要一个具体的香蕉工厂
    78. var bananaFac AbstractFactory
    79. bananaFac = new(BananaFactory)
    80. //2-生产相对应的具体水果
    81. var banana Fruit
    82. banana = bananaFac.CreateFruit()
    83. banana.Show()
    84. //需求3:需要一个具体的梨对象
    85. //1-先要一个具体的梨工厂
    86. var pearFac AbstractFactory
    87. pearFac = new(PearFactory)
    88. //2-生产相对应的具体水果
    89. var pear Fruit
    90. pear = pearFac.CreateFruit()
    91. pear.Show()
    92. //需求4:需要一个日本的苹果?
    93. }

    抽象工厂

    1. package main
    2. import "fmt"
    3. // ======= 抽象层 =========
    4. type AbstractApple interface {
    5. ShowApple()
    6. }
    7. type AbstractBanana interface {
    8. ShowBanana()
    9. }
    10. type AbstractPear interface {
    11. ShowPear()
    12. }
    13. //抽象工厂
    14. type AbstractFactory interface {
    15. CreateApple() AbstractApple
    16. CreateBanana() AbstractBanana
    17. CreatePear() AbstractPear
    18. }
    19. // ======== 实现层 =========
    20. /* 中国产品族 */
    21. type ChinaApple struct {}
    22. func (ca *ChinaApple) ShowApple() {
    23. fmt.Println("中国苹果")
    24. }
    25. type ChinaBanana struct {}
    26. func (cb *ChinaBanana) ShowBanana() {
    27. fmt.Println("中国香蕉")
    28. }
    29. type ChinaPear struct {}
    30. func (cp *ChinaPear) ShowPear() {
    31. fmt.Println("中国梨")
    32. }
    33. type ChinaFactory struct {}
    34. func (cf *ChinaFactory) CreateApple() AbstractApple {
    35. var apple AbstractApple
    36. apple = new(ChinaApple)
    37. return apple
    38. }
    39. func (cf *ChinaFactory) CreateBanana() AbstractBanana {
    40. var banana AbstractBanana
    41. banana = new(ChinaBanana)
    42. return banana
    43. }
    44. func (cf *ChinaFactory) CreatePear() AbstractPear {
    45. var pear AbstractPear
    46. pear = new(ChinaPear)
    47. return pear
    48. }
    49. /* 日本产品族 */
    50. type JapanApple struct {}
    51. func (ja *JapanApple) ShowApple() {
    52. fmt.Println("日本苹果")
    53. }
    54. type JapanBanana struct {}
    55. func (jb *JapanBanana) ShowBanana() {
    56. fmt.Println("日本香蕉")
    57. }
    58. type JapanPear struct {}
    59. func (cp *JapanPear) ShowPear() {
    60. fmt.Println("日本梨")
    61. }
    62. type JapanFactory struct {}
    63. func (jf *JapanFactory) CreateApple() AbstractApple {
    64. var apple AbstractApple
    65. apple = new(JapanApple)
    66. return apple
    67. }
    68. func (jf *JapanFactory) CreateBanana() AbstractBanana {
    69. var banana AbstractBanana
    70. banana = new(JapanBanana)
    71. return banana
    72. }
    73. func (cf *JapanFactory) CreatePear() AbstractPear {
    74. var pear AbstractPear
    75. pear = new(JapanPear)
    76. return pear
    77. }
    78. /* 美国产品族 */
    79. type AmericanApple struct {}
    80. func (aa *AmericanApple) ShowApple() {
    81. fmt.Println("美国苹果")
    82. }
    83. type AmericanBanana struct {}
    84. func (ab *AmericanBanana) ShowBanana() {
    85. fmt.Println("美国香蕉")
    86. }
    87. type AmericanPear struct {}
    88. func (ap *AmericanPear) ShowPear() {
    89. fmt.Println("美国梨")
    90. }
    91. type AmericanFactory struct {}
    92. func (af *AmericanFactory) CreateApple() AbstractApple {
    93. var apple AbstractApple
    94. apple = new(AmericanApple)
    95. return apple
    96. }
    97. func (af *AmericanFactory) CreateBanana() AbstractBanana {
    98. var banana AbstractBanana
    99. banana = new(AmericanBanana)
    100. return banana
    101. }
    102. func (af *AmericanFactory) CreatePear() AbstractPear {
    103. var pear AbstractPear
    104. pear = new(AmericanPear)
    105. return pear
    106. }
    107. // ======== 业务逻辑层 =======
    108. func main() {
    109. //需求1: 需要美国的苹果、香蕉、梨 等对象
    110. //1-创建一个美国工厂
    111. var aFac AbstractFactory
    112. aFac = new(AmericanFactory)
    113. //2-生产美国苹果
    114. var aApple AbstractApple
    115. aApple = aFac.CreateApple()
    116. aApple.ShowApple()
    117. //3-生产美国香蕉
    118. var aBanana AbstractBanana
    119. aBanana = aFac.CreateBanana()
    120. aBanana.ShowBanana()
    121. //4-生产美国梨
    122. var aPear AbstractPear
    123. aPear = aFac.CreatePear()
    124. aPear.ShowPear()
    125. //需求2: 需要中国的苹果、香蕉
    126. //1-创建一个中国工厂
    127. cFac := new(ChinaFactory)
    128. //2-生产中国苹果
    129. cApple := cFac.CreateApple()
    130. cApple.ShowApple()
    131. //3-生产中国香蕉
    132. cBanana := cFac.CreateBanana()
    133. cBanana.ShowBanana()
    134. }

    单例模式

    1. package main
    2. import "fmt"
    3. /*
    4. 三个要点:
    5. 一是某个类只能有一个实例;
    6. 二是它必须自行创建这个实例;
    7. 三是它必须自行向整个系统提供这个实例。
    8. */
    9. /*
    10. 保证一个类永远只能有一个对象
    11. */
    12. //1、保证这个类非公有化,外界不能通过这个类直接创建一个对象
    13. // 那么这个类就应该变得非公有访问 类名称首字母要小写
    14. type singelton struct {}
    15. //2、但是还要有一个指针可以指向这个唯一对象,但是这个指针永远不能改变方向
    16. // Golang中没有常指针概念,所以只能通过将这个指针私有化不让外部模块访问
    17. var instance *singelton = new(singelton)
    18. //3、如果全部为私有化,那么外部模块将永远无法访问到这个类和对象,
    19. // 所以需要对外提供一个方法来获取这个唯一实例对象
    20. // 注意:这个方法是否可以定义为singelton的一个成员方法呢?
    21. // 答案是不能,因为如果为成员方法就必须要先访问对象、再访问函数
    22. // 但是类和对象目前都已经私有化,外界无法访问,所以这个方法一定是一个全局普通函数
    23. func GetInstance() *singelton {
    24. return instance
    25. }
    26. func (s *singelton) SomeThing() {
    27. fmt.Println("单例对象的某方法")
    28. }
    29. func main() {
    30. s := GetInstance()
    31. s.SomeThing()
    32. }

    单例模式逻辑推演实现

    1. package main
    2. import "fmt"
    3. type singelton struct {}
    4. var instance *singelton
    5. func GetInstance() *singelton {
    6. //只有首次GetInstance()方法被调用,才会生成这个单例的实例
    7. if instance == nil {
    8. instance = new(singelton)
    9. return instance
    10. }
    11. //接下来的GetInstance直接返回已经申请的实例即可
    12. return instance
    13. }
    14. func (s *singelton) SomeThing() {
    15. fmt.Println("单例对象的某方法")
    16. }
    17. func main() {
    18. s := GetInstance()
    19. s.SomeThing()
    20. }
    1. package main
    2. import (
    3. "fmt"
    4. "sync"
    5. )
    6. //定义锁
    7. var lock sync.Mutex
    8. type singelton struct {}
    9. var instance *singelton
    10. func GetInstance() *singelton {
    11. //为了线程安全,增加互斥
    12. lock.Lock()
    13. defer lock.Unlock()
    14. if instance == nil {
    15. return new(singelton)
    16. } else {
    17. return instance
    18. }
    19. }
    20. func (s *singelton) SomeThing() {
    21. fmt.Println("单例对象的某方法")
    22. }
    23. func main() {
    24. s := GetInstance()
    25. s.SomeThing()
    26. }

    线程安全的单例模式实现

    1. package main
    2. import (
    3. "fmt"
    4. "sync"
    5. "sync/atomic"
    6. )
    7. //标记
    8. var initialized uint32
    9. var lock sync.Mutex
    10. type singelton struct {}
    11. var instance *singelton
    12. func GetInstance() *singelton {
    13. //如果标记为被设置,直接返回,不加锁
    14. if atomic.LoadUint32(&initialized) == 1 {
    15. return instance
    16. }
    17. //如果没有,则加锁申请
    18. lock.Lock()
    19. defer lock.Unlock()
    20. if initialized == 0 {
    21. instance = new(singelton)
    22. //设置标记位
    23. atomic.StoreUint32(&initialized, 1)
    24. }
    25. return instance
    26. }
    27. func (s *singelton) SomeThing() {
    28. fmt.Println("单例对象的某方法")
    29. }
    30. func main() {
    31. s := GetInstance()
    32. s.SomeThing()
    33. }
    1. func (o *Once) Do(f func()) {   //判断是否执行过该方法,如果执行过则不执行
    2. if atomic.LoadUint32(&o.done) == 1 {
    3. return
    4. }
    5. // Slow-path.
    6. o.m.Lock()
    7. defer o.m.Unlock()  
    8. if o.done == 0 {
    9. defer atomic.StoreUint32(&o.done, 1)
    10. f()
    11. }
    12. }
    1. package main
    2. import (
    3. "fmt"
    4. "sync"
    5. )
    6. var once sync.Once
    7. type singelton struct {}
    8. var instance *singelton
    9. func GetInstance() *singelton {
    10. once.Do(func(){
    11. instance = new(singelton)
    12. })
    13. return instance
    14. }
    15. func (s *singelton) SomeThing() {
    16. fmt.Println("单例对象的某方法")
    17. }
    18. func main() {
    19. s := GetInstance()
    20. s.SomeThing()
    21. }

    代理模式

    1. package main
    2. import "fmt"
    3. type Goods struct {
    4. Kind string //商品种类
    5. Fact bool //商品真伪
    6. }
    7. // =========== 抽象层 ===========
    8. //抽象的购物主题Subject
    9. type Shopping interface {
    10. Buy(goods *Goods) //某任务
    11. }
    12. // =========== 实现层 ===========
    13. //具体的购物主题, 实现了shopping, 去韩国购物
    14. type KoreaShopping struct {}
    15. func (ks *KoreaShopping) Buy(goods *Goods) {
    16. fmt.Println("去韩国进行了购物, 买了 ", goods.Kind)
    17. }
    18. //具体的购物主题, 实现了shopping, 去美国购物
    19. type AmericanShopping struct {}
    20. func (as *AmericanShopping) Buy(goods *Goods) {
    21. fmt.Println("去美国进行了购物, 买了 ", goods.Kind)
    22. }
    23. //具体的购物主题, 实现了shopping, 去非洲购物
    24. type AfrikaShopping struct {}
    25. func (as *AfrikaShopping) Buy(goods *Goods) {
    26. fmt.Println("去非洲进行了购物, 买了 ", goods.Kind)
    27. }
    28. //海外的代理
    29. type OverseasProxy struct {
    30. shopping Shopping //代理某个主题,这里是抽象类型
    31. }
    32. func (op *OverseasProxy) Buy(goods *Goods) {
    33. // 1. 先验货
    34. if (op.distinguish(goods) == true) {
    35. //2. 进行购买
    36. op.shopping.Buy(goods) //调用原被代理的具体主题任务
    37. //3 海关安检
    38. op.check(goods)
    39. }
    40. }
    41. //创建一个代理,并且配置关联被代理的主题
    42. func NewProxy(shopping Shopping) Shopping {
    43. return &OverseasProxy{shopping}
    44. }
    45. //验货流程
    46. func (op *OverseasProxy) distinguish(goods *Goods) bool {
    47. fmt.Println("对[", goods.Kind,"]进行了辨别真伪.")
    48. if (goods.Fact == false) {
    49. fmt.Println("发现假货",goods.Kind,", 不应该购买。")
    50. }
    51. return goods.Fact
    52. }
    53. //安检流程
    54. func (op *OverseasProxy) check(goods *Goods) {
    55. fmt.Println("对[",goods.Kind,"] 进行了海关检查, 成功的带回祖国")
    56. }
    57. func main() {
    58. g1 := Goods{
    59. Kind: "韩国面膜",
    60. Fact: true,
    61. }
    62. g2 := Goods{
    63. Kind: "CET4证书",
    64. Fact: false,
    65. }
    66. //如果不使用代理来完成从韩国购买任务
    67. var shopping Shopping
    68. shopping = new(KoreaShopping) //具体的购买主题
    69. //1-先验货
    70. if g1.Fact == true {
    71. fmt.Println("对[", g1.Kind,"]进行了辨别真伪.")
    72. //2-去韩国购买
    73. shopping.Buy(&g1)
    74. //3-海关安检
    75. fmt.Println("对[",g1.Kind,"] 进行了海关检查, 成功的带回祖国")
    76. }
    77. fmt.Println("---------------以下是 使用 代理模式-------")
    78. var overseasProxy Shopping
    79. overseasProxy = NewProxy(shopping)
    80. overseasProxy.Buy(&g1)
    81. overseasProxy.Buy(&g2)
    82. }
    1. package main
    2. import "fmt"
    3. //抽象主题
    4. type BeautyWoman interface {
    5. //对男人抛媚眼
    6. MakeEyesWithMan()
    7. //和男人浪漫的约会
    8. HappyWithMan()
    9. }
    10. //具体主题
    11. type PanJinLian struct {}
    12. //对男人抛媚眼
    13. func (p *PanJinLian) MakeEyesWithMan() {
    14. fmt.Println("潘金莲对本官抛了个媚眼")
    15. }
    16. //和男人浪漫的约会
    17. func (p *PanJinLian) HappyWithMan() {
    18. fmt.Println("潘金莲和本官共度了浪漫的约会。")
    19. }
    20. //代理中介人, 王婆
    21. type WangPo struct {
    22. woman BeautyWoman
    23. }
    24. func NewProxy(woman BeautyWoman) BeautyWoman {
    25. return &WangPo{woman}
    26. }
    27. //对男人抛媚眼
    28. func (p *WangPo) MakeEyesWithMan() {
    29. p.woman.MakeEyesWithMan()
    30. }
    31. //和男人浪漫的约会
    32. func (p *WangPo) HappyWithMan() {
    33. p.woman.HappyWithMan()
    34. }
    35. //西门大官人
    36. func main() {
    37. //大官人想找金莲,让王婆来安排
    38. wangpo := NewProxy(new(PanJinLian))
    39. //王婆命令潘金莲抛媚眼
    40. wangpo.MakeEyesWithMan()
    41. //王婆命令潘金莲和西门庆约会
    42. wangpo.HappyWithMan()
    43. }

    装饰模式

    1. package main
    2. import "fmt"
    3. // ---------- 抽象层 ----------
    4. //抽象的构件
    5. type Phone interface {
    6. Show() //构件的功能
    7. }
    8. //装饰器基础类(该类本应该为interface,但是Golang interface语法不可以有成员属性)
    9. type Decorator struct {
    10. phone Phone
    11. }
    12. func (d *Decorator) Show() {}
    13. // ----------- 实现层 -----------
    14. // 具体的构件
    15. type HuaWei struct {}
    16. func (hw *HuaWei) Show() {
    17. fmt.Println("秀出了HuaWei手机")
    18. }
    19. type XiaoMi struct{}
    20. func (xm *XiaoMi) Show() {
    21. fmt.Println("秀出了XiaoMi手机")
    22. }
    23. // 具体的装饰器类
    24. type MoDecorator struct {
    25. Decorator //继承基础装饰器类(主要继承Phone成员属性)
    26. }
    27. func (md *MoDecorator) Show() {
    28. md.phone.Show() //调用被装饰构件的原方法
    29. fmt.Println("贴膜的手机") //装饰额外的方法
    30. }
    31. func NewMoDecorator(phone Phone) Phone {
    32. return &MoDecorator{Decorator{phone}}
    33. }
    34. type KeDecorator struct {
    35. Decorator //继承基础装饰器类(主要继承Phone成员属性)
    36. }
    37. func (kd *KeDecorator) Show() {
    38. kd.phone.Show()
    39. fmt.Println("手机壳的手机") //装饰额外的方法
    40. }
    41. func NewKeDecorator(phone Phone) Phone {
    42. return &KeDecorator{Decorator{phone}}
    43. }
    44. // ------------ 业务逻辑层 ---------
    45. func main() {
    46. var huawei Phone
    47. huawei = new(HuaWei)
    48. huawei.Show() //调用原构件方法
    49. fmt.Println("---------")
    50. //用贴膜装饰器装饰,得到新功能构件
    51. var moHuawei Phone
    52. moHuawei = NewMoDecorator(huawei) //通过HueWei ---> MoHuaWei
    53. moHuawei.Show() //调用装饰后新构件的方法
    54. fmt.Println("---------")
    55. var keHuawei Phone
    56. keHuawei = NewKeDecorator(huawei) //通过HueWei ---> KeHuaWei
    57. keHuawei.Show()
    58. fmt.Println("---------")
    59. var keMoHuaWei Phone
    60. keMoHuaWei = NewMoDecorator(keHuawei) //通过KeHuaWei ---> KeMoHuaWei
    61. keMoHuaWei.Show()
    62. }

    适配器模式

    1. package main
    2. import "fmt"
    3. //适配的目标
    4. type V5 interface {
    5. Use5V()
    6. }
    7. //业务类,依赖V5接口
    8. type Phone struct {
    9. v V5
    10. }
    11. func NewPhone(v V5) *Phone {
    12. return &Phone{v}
    13. }
    14. func (p *Phone) Charge() {
    15. fmt.Println("Phone进行充电...")
    16. p.v.Use5V()
    17. }
    18. //被适配的角色,适配者
    19. type V220 struct {}
    20. func (v *V220) Use220V() {
    21. fmt.Println("使用220V的电压")
    22. }
    23. //电源适配器
    24. type Adapter struct {
    25. v220 *V220
    26. }
    27. func (a *Adapter) Use5V() {
    28. fmt.Println("使用适配器进行充电")
    29. //调用适配者的方法
    30. a.v220.Use220V()
    31. }
    32. func NewAdapter(v220 *V220) *Adapter {
    33. return &Adapter{v220}
    34. }
    35. // ------- 业务逻辑层 -------
    36. func main() {
    37. iphone := NewPhone(NewAdapter(new(V220)))
    38. iphone.Charge()
    39. }

    外观模式

    1. package main
    2. import "fmt"
    3. type SubSystemA struct {}
    4. func (sa *SubSystemA) MethodA() {
    5. fmt.Println("子系统方法A")
    6. }
    7. type SubSystemB struct {}
    8. func (sb *SubSystemB) MethodB() {
    9. fmt.Println("子系统方法B")
    10. }
    11. type SubSystemC struct {}
    12. func (sc *SubSystemC) MethodC() {
    13. fmt.Println("子系统方法C")
    14. }
    15. type SubSystemD struct {}
    16. func (sd *SubSystemD) MethodD() {
    17. fmt.Println("子系统方法D")
    18. }
    19. //外观模式,提供了一个外观类, 简化成一个简单的接口供使用
    20. type Facade struct {
    21. a *SubSystemA
    22. b *SubSystemB
    23. c *SubSystemC
    24. d *SubSystemD
    25. }
    26. func (f *Facade) MethodOne() {
    27. f.a.MethodA()
    28. f.b.MethodB()
    29. }
    30. func (f *Facade) MethodTwo() {
    31. f.c.MethodC()
    32. f.d.MethodD()
    33. }
    34. func main() {
    35. //如果不用外观模式实现MethodA() 和 MethodB()
    36. sa := new(SubSystemA)
    37. sa.MethodA()
    38. sb := new(SubSystemB)
    39. sb.MethodB()
    40. fmt.Println("-----------")
    41. //使用外观模式
    42. f := Facade{
    43. a: new(SubSystemA),
    44. b: new(SubSystemB),
    45. c: new(SubSystemC),
    46. d: new(SubSystemD),
    47. }
    48. //调用外观包裹方法
    49. f.MethodOne()
    50. }

    模板模式

    1. package main
    2. import "fmt"
    3. //抽象类,制作饮料,包裹一个模板的全部实现步骤
    4. type Beverage interface {
    5. BoilWater() //煮开水
    6. Brew() //冲泡
    7. PourInCup() //倒入杯中
    8. AddThings() //添加酌料
    9. WantAddThings() bool //是否加入酌料Hook
    10. }
    11. //封装一套流程模板,让具体的制作流程继承且实现
    12. type template struct {
    13. b Beverage
    14. }
    15. //封装的固定模板
    16. func (t *template) MakeBeverage() {
    17. if t == nil {
    18. return
    19. }
    20. t.b.BoilWater()
    21. t.b.Brew()
    22. t.b.PourInCup()
    23. //子类可以重写该方法来决定是否执行下面动作
    24. if t.b.WantAddThings() == true {
    25. t.b.AddThings()
    26. }
    27. }
    28. //具体的模板子类 制作咖啡
    29. type MakeCaffee struct {
    30. template //继承模板
    31. }
    32. func NewMakeCaffee() *MakeCaffee {
    33. makeCaffe := new(MakeCaffee)
    34. //b 为Beverage,是MakeCaffee的接口,这里需要给接口赋值,指向具体的子类对象
    35. //来触发b全部接口方法的多态特性。
    36. makeCaffe.b = makeCaffe
    37. return makeCaffe
    38. }
    39. func (mc *MakeCaffee) BoilWater() {
    40. fmt.Println("将水煮到100摄氏度")
    41. }
    42. func (mc *MakeCaffee) Brew() {
    43. fmt.Println("用水冲咖啡豆")
    44. }
    45. func (mc *MakeCaffee) PourInCup() {
    46. fmt.Println("将充好的咖啡倒入陶瓷杯中")
    47. }
    48. func (mc *MakeCaffee) AddThings() {
    49. fmt.Println("添加牛奶和糖")
    50. }
    51. func (mc *MakeCaffee) WantAddThings() bool {
    52. return true //启动Hook条件
    53. }
    54. //具体的模板子类 制作茶
    55. type MakeTea struct {
    56. template //继承模板
    57. }
    58. func NewMakeTea() *MakeTea {
    59. makeTea := new(MakeTea)
    60. //b 为Beverage,是MakeTea,这里需要给接口赋值,指向具体的子类对象
    61. //来触发b全部接口方法的多态特性。
    62. makeTea.b = makeTea
    63. return makeTea
    64. }
    65. func (mt *MakeTea) BoilWater() {
    66. fmt.Println("将水煮到80摄氏度")
    67. }
    68. func (mt *MakeTea) Brew() {
    69. fmt.Println("用水冲茶叶")
    70. }
    71. func (mt *MakeTea) PourInCup() {
    72. fmt.Println("将充好的咖啡倒入茶壶中")
    73. }
    74. func (mt *MakeTea) AddThings() {
    75. fmt.Println("添加柠檬")
    76. }
    77. func (mt *MakeTea) WantAddThings() bool {
    78. return false //关闭Hook条件
    79. }
    80. func main() {
    81. //1. 制作一杯咖啡
    82. makeCoffee := NewMakeCaffee()
    83. makeCoffee.MakeBeverage() //调用固定模板方法
    84. fmt.Println("------------")
    85. //2. 制作茶
    86. makeTea := NewMakeTea()
    87. makeTea.MakeBeverage()
    88. }

    命令模式

    1. package main
    2. import "fmt"
    3. //医生-命令接收者
    4. type Doctor struct {}
    5. func (d *Doctor) treatEye() {
    6. fmt.Println("医生治疗眼睛")
    7. }
    8. func (d *Doctor) treatNose() {
    9. fmt.Println("医生治疗鼻子")
    10. }
    11. //抽象的命令
    12. type Command interface {
    13. Treat()
    14. }
    15. //治疗眼睛的病单
    16. type CommandTreatEye struct {
    17. doctor *Doctor
    18. }
    19. func (cmd *CommandTreatEye) Treat() {
    20. cmd.doctor.treatEye()
    21. }
    22. //治疗鼻子的病单
    23. type CommandTreatNose struct {
    24. doctor *Doctor
    25. }
    26. func (cmd *CommandTreatNose) Treat() {
    27. cmd.doctor.treatNose()
    28. }
    29. //护士-调用命令者
    30. type Nurse struct {
    31. CmdList []Command //收集的命令集合
    32. }
    33. //发送病单,发送命令的方法
    34. func (n *Nurse) Notify() {
    35. if n.CmdList == nil {
    36. return
    37. }
    38. for _, cmd := range n.CmdList {
    39. cmd.Treat() //执行病单绑定的命令(这里会调用病单已经绑定的医生的诊断方法)
    40. }
    41. }
    42. //病人
    43. func main() {
    44. //依赖病单,通过填写病单,让医生看病
    45. doctor := new(Doctor)
    46. //治疗眼睛的病单
    47. cmdEye := CommandTreatEye{doctor}
    48. //治疗鼻子的病单
    49. cmdNose := CommandTreatNose{doctor}
    50. //护士
    51. nurse := new(Nurse)
    52. //收集管理病单
    53. nurse.CmdList = append(nurse.CmdList, &cmdEye)
    54. nurse.CmdList = append(nurse.CmdList, &cmdNose)
    55. //执行病单指令
    56. nurse.Notify()
    57. }
    1. package main
    2. import "fmt"
    3. type Cooker struct {}
    4. func (c *Cooker) MakeChicken() {
    5. fmt.Println("烤串师傅烤了鸡肉串儿")
    6. }
    7. func (c *Cooker) MakeChuaner() {
    8. fmt.Println("烤串师傅烤了羊肉串儿")
    9. }
    10. //抽象的命令
    11. type Command interface {
    12. Make()
    13. }
    14. type CommandCookChicken struct {
    15. cooker *Cooker
    16. }
    17. func (cmd *CommandCookChicken) Make() {
    18. cmd.cooker.MakeChicken()
    19. }
    20. type CommandCookChuaner struct {
    21. cooker *Cooker
    22. }
    23. func (cmd *CommandCookChuaner) Make() {
    24. cmd.cooker.MakeChuaner()
    25. }
    26. type WaiterMM struct {
    27. CmdList []Command //收集的命令集合
    28. }
    29. func (w *WaiterMM) Notify() {
    30. if w.CmdList == nil {
    31. return
    32. }
    33. for _, cmd := range w.CmdList {
    34. cmd.Make()
    35. }
    36. }
    37. func main() {
    38. cooker := new(Cooker)
    39. cmdChicken := CommandCookChicken{cooker}
    40. cmdChuaner := CommandCookChuaner{cooker}
    41. mm := new(WaiterMM)
    42. mm.CmdList = append(mm.CmdList, &cmdChicken)
    43. mm.CmdList = append(mm.CmdList, &cmdChuaner)
    44. mm.Notify()
    45. }

    策略模式

    1. package main
    2. import "fmt"
    3. //武器策略(抽象的策略)
    4. type WeaponStrategy interface {
    5. UseWeapon() //使用武器
    6. }
    7. //具体的策略
    8. type Ak47 struct {}
    9. func (ak *Ak47) UseWeapon() {
    10. fmt.Println("使用Ak47 去战斗")
    11. }
    12. //具体的策略
    13. type Knife struct {}
    14. func (k *Knife) UseWeapon() {
    15. fmt.Println("使用匕首 去战斗")
    16. }
    17. //环境类
    18. type Hero struct {
    19. strategy WeaponStrategy //拥有一个抽象的策略
    20. }
    21. //设置一个策略
    22. func (h *Hero) SetWeaponStrategy(s WeaponStrategy) {
    23. h.strategy = s
    24. }
    25. func (h *Hero) Fight() {
    26. h.strategy.UseWeapon() //调用策略
    27. }
    28. func main() {
    29. hero := Hero{}
    30. //更换策略1
    31. hero.SetWeaponStrategy(new(Ak47))
    32. hero.Fight()
    33. hero.SetWeaponStrategy(new(Knife))
    34. hero.Fight()
    35. }
    1. package main
    2. import "fmt"
    3. /*
    4. 练习:
    5. 商场促销有策略A(0.8折)策略B(消费满200,返现100),用策略模式模拟场景
    6. */
    7. //销售策略
    8. type SellStrategy interface {
    9. //根据原价得到售卖价
    10. GetPrice(price float64) float64
    11. }
    12. type StrategyA struct {}
    13. func (sa *StrategyA) GetPrice(price float64) float64 {
    14. fmt.Println("执行策略A, 所有商品打八折")
    15. return price * 0.8;
    16. }
    17. type StrategyB struct {}
    18. func (sb *StrategyB) GetPrice(price float64) float64 {
    19. fmt.Println("执行策略B, 所有商品满200 减100")
    20. if price >= 200 {
    21. price -= 100
    22. }
    23. return price;
    24. }
    25. //环境类
    26. type Goods struct {
    27. Price float64
    28. Strategy SellStrategy
    29. }
    30. func (g *Goods) SetStrategy(s SellStrategy) {
    31. g.Strategy = s
    32. }
    33. func (g *Goods) SellPrice() float64 {
    34. fmt.Println("原价值 ", g.Price , " .")
    35. return g.Strategy.GetPrice(g.Price)
    36. }
    37. func main() {
    38. nike := Goods{
    39. Price: 200.0,
    40. }
    41. //上午 ,商场执行策略A
    42. nike.SetStrategy(new(StrategyA))
    43. fmt.Println("上午nike鞋卖", nike.SellPrice())
    44. //下午, 商场执行策略B
    45. nike.SetStrategy(new(StrategyB))
    46. fmt.Println("下午nike鞋卖", nike.SellPrice())
    47. }

    观察者模式

    1. package main
    2. import "fmt"
    3. //--------- 抽象层 --------
    4. //抽象的观察者
    5. type Listener interface {
    6. OnTeacherComming() //观察者得到通知后要触发的动作
    7. }
    8. type Notifier interface {
    9. AddListener(listener Listener)
    10. RemoveListener(listener Listener)
    11. Notify()
    12. }
    13. //--------- 实现层 --------
    14. //观察者学生
    15. type StuZhang3 struct {
    16. Badthing string
    17. }
    18. func (s *StuZhang3) OnTeacherComming() {
    19. fmt.Println("张3 停止 ", s.Badthing)
    20. }
    21. func (s *StuZhang3) DoBadthing() {
    22. fmt.Println("张3 正在", s.Badthing)
    23. }
    24. type StuZhao4 struct {
    25. Badthing string
    26. }
    27. func (s *StuZhao4) OnTeacherComming() {
    28. fmt.Println("赵4 停止 ", s.Badthing)
    29. }
    30. func (s *StuZhao4) DoBadthing() {
    31. fmt.Println("赵4 正在", s.Badthing)
    32. }
    33. type StuWang5 struct {
    34. Badthing string
    35. }
    36. func (s *StuWang5) OnTeacherComming() {
    37. fmt.Println("王5 停止 ", s.Badthing)
    38. }
    39. func (s *StuWang5) DoBadthing() {
    40. fmt.Println("王5 正在", s.Badthing)
    41. }
    42. //通知者班长
    43. type ClassMonitor struct {
    44. listenerList []Listener //需要通知的全部观察者集合
    45. }
    46. func (m *ClassMonitor) AddListener(listener Listener) {
    47. m.listenerList = append(m.listenerList, listener)
    48. }
    49. func (m *ClassMonitor) RemoveListener(listener Listener) {
    50. for index, l := range m.listenerList {
    51. //找到要删除的元素位置
    52. if listener == l {
    53. //将删除的点前后的元素链接起来
    54. m.listenerList = append(m.listenerList[:index], m.listenerList[index+1:]...)
    55. break
    56. }
    57. }
    58. }
    59. func (m* ClassMonitor) Notify() {
    60. for _, listener := range m.listenerList {
    61. //依次调用全部观察的具体动作
    62. listener.OnTeacherComming()
    63. }
    64. }
    65. func main() {
    66. s1 := &StuZhang3{
    67. Badthing: "抄作业",
    68. }
    69. s2 := &StuZhao4{
    70. Badthing: "玩王者荣耀",
    71. }
    72. s3 := &StuWang5{
    73. Badthing: "看赵四玩王者荣耀",
    74. }
    75. classMonitor := new(ClassMonitor)
    76. fmt.Println("上课了,但是老师没有来,学生们都在忙自己的事...")
    77. s1.DoBadthing()
    78. s2.DoBadthing()
    79. s3.DoBadthing()
    80. classMonitor.AddListener(s1)
    81. classMonitor.AddListener(s2)
    82. classMonitor.AddListener(s3)
    83. fmt.Println("这时候老师来了,班长给学什么使了一个眼神...")
    84. classMonitor.Notify()
    85. }

    参考:https://www.yuque.com/aceld/lfhu8y/en7x5c