简单工厂模式
package mainimport "fmt"// ======= 抽象层 =========//水果类(抽象接口)type Fruit interface {Show() //接口的某方法}// ======= 基础类模块 =========type Apple struct {Fruit //为了易于理解显示继承(此行可以省略)}func (apple *Apple) Show() {fmt.Println("我是苹果")}type Banana struct {Fruit}func (banana *Banana) Show() {fmt.Println("我是香蕉")}type Pear struct {Fruit}func (pear *Pear) Show() {fmt.Println("我是梨")}// ========= 工厂模块 =========//一个工厂, 有一个生产水果的机器,返回一个抽象水果的指针type Factory struct {}func (fac *Factory) CreateFruit(kind string) Fruit {var fruit Fruitif kind == "apple" {fruit = new(Apple)} else if kind == "banana" {fruit = new(Banana)} else if kind == "pear" {fruit = new(Pear)}return fruit}// ==========业务逻辑层==============func main() {factory := new(Factory)apple := factory.CreateFruit("apple")apple.Show()banana := factory.CreateFruit("banana")banana.Show()pear := factory.CreateFruit("pear")pear.Show()}
工厂方式
package mainimport "fmt"// ======= 抽象层 =========//水果类(抽象接口)type Fruit interface {Show() //接口的某方法}//工厂类(抽象接口)type AbstractFactory interface {CreateFruit() Fruit //生产水果类(抽象)的生产器方法}// ======= 基础类模块 =========type Apple struct {Fruit //为了易于理解显示继承(此行可以省略)}func (apple *Apple) Show() {fmt.Println("我是苹果")}type Banana struct {Fruit}func (banana *Banana) Show() {fmt.Println("我是香蕉")}type Pear struct {Fruit}func (pear *Pear) Show() {fmt.Println("我是梨")}// ========= 工厂模块 =========//具体的苹果工厂type AppleFactory struct {AbstractFactory}func (fac *AppleFactory) CreateFruit() Fruit {var fruit Fruit//生产一个具体的苹果fruit = new(Apple)return fruit}//具体的香蕉工厂type BananaFactory struct {AbstractFactory}func (fac *BananaFactory) CreateFruit() Fruit {var fruit Fruit//生产一个具体的香蕉fruit = new(Banana)return fruit}//具体的梨工厂type PearFactory struct {AbstractFactory}func (fac *PearFactory) CreateFruit() Fruit {var fruit Fruit//生产一个具体的梨fruit = new(Pear)return fruit}//======= 业务逻辑层 =======func main() {/*本案例为了突出根据依赖倒转原则与面向接口编程特性。一些变量的定义将使用显示类型声明方式*///需求1:需要一个具体的苹果对象//1-先要一个具体的苹果工厂var appleFac AbstractFactoryappleFac = new(AppleFactory)//2-生产相对应的具体水果var apple Fruitapple = appleFac.CreateFruit()apple.Show()//需求2:需要一个具体的香蕉对象//1-先要一个具体的香蕉工厂var bananaFac AbstractFactorybananaFac = new(BananaFactory)//2-生产相对应的具体水果var banana Fruitbanana = bananaFac.CreateFruit()banana.Show()//需求3:需要一个具体的梨对象//1-先要一个具体的梨工厂var pearFac AbstractFactorypearFac = new(PearFactory)//2-生产相对应的具体水果var pear Fruitpear = pearFac.CreateFruit()pear.Show()//需求4:需要一个日本的苹果?}
抽象工厂
package mainimport "fmt"// ======= 抽象层 =========type AbstractApple interface {ShowApple()}type AbstractBanana interface {ShowBanana()}type AbstractPear interface {ShowPear()}//抽象工厂type AbstractFactory interface {CreateApple() AbstractAppleCreateBanana() AbstractBananaCreatePear() AbstractPear}// ======== 实现层 =========/* 中国产品族 */type ChinaApple struct {}func (ca *ChinaApple) ShowApple() {fmt.Println("中国苹果")}type ChinaBanana struct {}func (cb *ChinaBanana) ShowBanana() {fmt.Println("中国香蕉")}type ChinaPear struct {}func (cp *ChinaPear) ShowPear() {fmt.Println("中国梨")}type ChinaFactory struct {}func (cf *ChinaFactory) CreateApple() AbstractApple {var apple AbstractAppleapple = new(ChinaApple)return apple}func (cf *ChinaFactory) CreateBanana() AbstractBanana {var banana AbstractBananabanana = new(ChinaBanana)return banana}func (cf *ChinaFactory) CreatePear() AbstractPear {var pear AbstractPearpear = new(ChinaPear)return pear}/* 日本产品族 */type JapanApple struct {}func (ja *JapanApple) ShowApple() {fmt.Println("日本苹果")}type JapanBanana struct {}func (jb *JapanBanana) ShowBanana() {fmt.Println("日本香蕉")}type JapanPear struct {}func (cp *JapanPear) ShowPear() {fmt.Println("日本梨")}type JapanFactory struct {}func (jf *JapanFactory) CreateApple() AbstractApple {var apple AbstractAppleapple = new(JapanApple)return apple}func (jf *JapanFactory) CreateBanana() AbstractBanana {var banana AbstractBananabanana = new(JapanBanana)return banana}func (cf *JapanFactory) CreatePear() AbstractPear {var pear AbstractPearpear = new(JapanPear)return pear}/* 美国产品族 */type AmericanApple struct {}func (aa *AmericanApple) ShowApple() {fmt.Println("美国苹果")}type AmericanBanana struct {}func (ab *AmericanBanana) ShowBanana() {fmt.Println("美国香蕉")}type AmericanPear struct {}func (ap *AmericanPear) ShowPear() {fmt.Println("美国梨")}type AmericanFactory struct {}func (af *AmericanFactory) CreateApple() AbstractApple {var apple AbstractAppleapple = new(AmericanApple)return apple}func (af *AmericanFactory) CreateBanana() AbstractBanana {var banana AbstractBananabanana = new(AmericanBanana)return banana}func (af *AmericanFactory) CreatePear() AbstractPear {var pear AbstractPearpear = new(AmericanPear)return pear}// ======== 业务逻辑层 =======func main() {//需求1: 需要美国的苹果、香蕉、梨 等对象//1-创建一个美国工厂var aFac AbstractFactoryaFac = new(AmericanFactory)//2-生产美国苹果var aApple AbstractAppleaApple = aFac.CreateApple()aApple.ShowApple()//3-生产美国香蕉var aBanana AbstractBananaaBanana = aFac.CreateBanana()aBanana.ShowBanana()//4-生产美国梨var aPear AbstractPearaPear = aFac.CreatePear()aPear.ShowPear()//需求2: 需要中国的苹果、香蕉//1-创建一个中国工厂cFac := new(ChinaFactory)//2-生产中国苹果cApple := cFac.CreateApple()cApple.ShowApple()//3-生产中国香蕉cBanana := cFac.CreateBanana()cBanana.ShowBanana()}
单例模式
package mainimport "fmt"/*三个要点:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。*//*保证一个类永远只能有一个对象*///1、保证这个类非公有化,外界不能通过这个类直接创建一个对象// 那么这个类就应该变得非公有访问 类名称首字母要小写type singelton struct {}//2、但是还要有一个指针可以指向这个唯一对象,但是这个指针永远不能改变方向// Golang中没有常指针概念,所以只能通过将这个指针私有化不让外部模块访问var instance *singelton = new(singelton)//3、如果全部为私有化,那么外部模块将永远无法访问到这个类和对象,// 所以需要对外提供一个方法来获取这个唯一实例对象// 注意:这个方法是否可以定义为singelton的一个成员方法呢?// 答案是不能,因为如果为成员方法就必须要先访问对象、再访问函数// 但是类和对象目前都已经私有化,外界无法访问,所以这个方法一定是一个全局普通函数func GetInstance() *singelton {return instance}func (s *singelton) SomeThing() {fmt.Println("单例对象的某方法")}func main() {s := GetInstance()s.SomeThing()}
单例模式逻辑推演实现
package mainimport "fmt"type singelton struct {}var instance *singeltonfunc GetInstance() *singelton {//只有首次GetInstance()方法被调用,才会生成这个单例的实例if instance == nil {instance = new(singelton)return instance}//接下来的GetInstance直接返回已经申请的实例即可return instance}func (s *singelton) SomeThing() {fmt.Println("单例对象的某方法")}func main() {s := GetInstance()s.SomeThing()}
package mainimport ("fmt""sync")//定义锁var lock sync.Mutextype singelton struct {}var instance *singeltonfunc GetInstance() *singelton {//为了线程安全,增加互斥lock.Lock()defer lock.Unlock()if instance == nil {return new(singelton)} else {return instance}}func (s *singelton) SomeThing() {fmt.Println("单例对象的某方法")}func main() {s := GetInstance()s.SomeThing()}
线程安全的单例模式实现
package mainimport ("fmt""sync""sync/atomic")//标记var initialized uint32var lock sync.Mutextype singelton struct {}var instance *singeltonfunc GetInstance() *singelton {//如果标记为被设置,直接返回,不加锁if atomic.LoadUint32(&initialized) == 1 {return instance}//如果没有,则加锁申请lock.Lock()defer lock.Unlock()if initialized == 0 {instance = new(singelton)//设置标记位atomic.StoreUint32(&initialized, 1)}return instance}func (s *singelton) SomeThing() {fmt.Println("单例对象的某方法")}func main() {s := GetInstance()s.SomeThing()}
func (o *Once) Do(f func()) { //判断是否执行过该方法,如果执行过则不执行if atomic.LoadUint32(&o.done) == 1 {return}// Slow-path.o.m.Lock()defer o.m.Unlock()if o.done == 0 {defer atomic.StoreUint32(&o.done, 1)f()}}
package mainimport ("fmt""sync")var once sync.Oncetype singelton struct {}var instance *singeltonfunc GetInstance() *singelton {once.Do(func(){instance = new(singelton)})return instance}func (s *singelton) SomeThing() {fmt.Println("单例对象的某方法")}func main() {s := GetInstance()s.SomeThing()}
代理模式
package mainimport "fmt"type Goods struct {Kind string //商品种类Fact bool //商品真伪}// =========== 抽象层 ===========//抽象的购物主题Subjecttype Shopping interface {Buy(goods *Goods) //某任务}// =========== 实现层 ===========//具体的购物主题, 实现了shopping, 去韩国购物type KoreaShopping struct {}func (ks *KoreaShopping) Buy(goods *Goods) {fmt.Println("去韩国进行了购物, 买了 ", goods.Kind)}//具体的购物主题, 实现了shopping, 去美国购物type AmericanShopping struct {}func (as *AmericanShopping) Buy(goods *Goods) {fmt.Println("去美国进行了购物, 买了 ", goods.Kind)}//具体的购物主题, 实现了shopping, 去非洲购物type AfrikaShopping struct {}func (as *AfrikaShopping) Buy(goods *Goods) {fmt.Println("去非洲进行了购物, 买了 ", goods.Kind)}//海外的代理type OverseasProxy struct {shopping Shopping //代理某个主题,这里是抽象类型}func (op *OverseasProxy) Buy(goods *Goods) {// 1. 先验货if (op.distinguish(goods) == true) {//2. 进行购买op.shopping.Buy(goods) //调用原被代理的具体主题任务//3 海关安检op.check(goods)}}//创建一个代理,并且配置关联被代理的主题func NewProxy(shopping Shopping) Shopping {return &OverseasProxy{shopping}}//验货流程func (op *OverseasProxy) distinguish(goods *Goods) bool {fmt.Println("对[", goods.Kind,"]进行了辨别真伪.")if (goods.Fact == false) {fmt.Println("发现假货",goods.Kind,", 不应该购买。")}return goods.Fact}//安检流程func (op *OverseasProxy) check(goods *Goods) {fmt.Println("对[",goods.Kind,"] 进行了海关检查, 成功的带回祖国")}func main() {g1 := Goods{Kind: "韩国面膜",Fact: true,}g2 := Goods{Kind: "CET4证书",Fact: false,}//如果不使用代理来完成从韩国购买任务var shopping Shoppingshopping = new(KoreaShopping) //具体的购买主题//1-先验货if g1.Fact == true {fmt.Println("对[", g1.Kind,"]进行了辨别真伪.")//2-去韩国购买shopping.Buy(&g1)//3-海关安检fmt.Println("对[",g1.Kind,"] 进行了海关检查, 成功的带回祖国")}fmt.Println("---------------以下是 使用 代理模式-------")var overseasProxy ShoppingoverseasProxy = NewProxy(shopping)overseasProxy.Buy(&g1)overseasProxy.Buy(&g2)}
package mainimport "fmt"//抽象主题type BeautyWoman interface {//对男人抛媚眼MakeEyesWithMan()//和男人浪漫的约会HappyWithMan()}//具体主题type PanJinLian struct {}//对男人抛媚眼func (p *PanJinLian) MakeEyesWithMan() {fmt.Println("潘金莲对本官抛了个媚眼")}//和男人浪漫的约会func (p *PanJinLian) HappyWithMan() {fmt.Println("潘金莲和本官共度了浪漫的约会。")}//代理中介人, 王婆type WangPo struct {woman BeautyWoman}func NewProxy(woman BeautyWoman) BeautyWoman {return &WangPo{woman}}//对男人抛媚眼func (p *WangPo) MakeEyesWithMan() {p.woman.MakeEyesWithMan()}//和男人浪漫的约会func (p *WangPo) HappyWithMan() {p.woman.HappyWithMan()}//西门大官人func main() {//大官人想找金莲,让王婆来安排wangpo := NewProxy(new(PanJinLian))//王婆命令潘金莲抛媚眼wangpo.MakeEyesWithMan()//王婆命令潘金莲和西门庆约会wangpo.HappyWithMan()}
装饰模式
package mainimport "fmt"// ---------- 抽象层 ----------//抽象的构件type Phone interface {Show() //构件的功能}//装饰器基础类(该类本应该为interface,但是Golang interface语法不可以有成员属性)type Decorator struct {phone Phone}func (d *Decorator) Show() {}// ----------- 实现层 -----------// 具体的构件type HuaWei struct {}func (hw *HuaWei) Show() {fmt.Println("秀出了HuaWei手机")}type XiaoMi struct{}func (xm *XiaoMi) Show() {fmt.Println("秀出了XiaoMi手机")}// 具体的装饰器类type MoDecorator struct {Decorator //继承基础装饰器类(主要继承Phone成员属性)}func (md *MoDecorator) Show() {md.phone.Show() //调用被装饰构件的原方法fmt.Println("贴膜的手机") //装饰额外的方法}func NewMoDecorator(phone Phone) Phone {return &MoDecorator{Decorator{phone}}}type KeDecorator struct {Decorator //继承基础装饰器类(主要继承Phone成员属性)}func (kd *KeDecorator) Show() {kd.phone.Show()fmt.Println("手机壳的手机") //装饰额外的方法}func NewKeDecorator(phone Phone) Phone {return &KeDecorator{Decorator{phone}}}// ------------ 业务逻辑层 ---------func main() {var huawei Phonehuawei = new(HuaWei)huawei.Show() //调用原构件方法fmt.Println("---------")//用贴膜装饰器装饰,得到新功能构件var moHuawei PhonemoHuawei = NewMoDecorator(huawei) //通过HueWei ---> MoHuaWeimoHuawei.Show() //调用装饰后新构件的方法fmt.Println("---------")var keHuawei PhonekeHuawei = NewKeDecorator(huawei) //通过HueWei ---> KeHuaWeikeHuawei.Show()fmt.Println("---------")var keMoHuaWei PhonekeMoHuaWei = NewMoDecorator(keHuawei) //通过KeHuaWei ---> KeMoHuaWeikeMoHuaWei.Show()}
适配器模式
package mainimport "fmt"//适配的目标type V5 interface {Use5V()}//业务类,依赖V5接口type Phone struct {v V5}func NewPhone(v V5) *Phone {return &Phone{v}}func (p *Phone) Charge() {fmt.Println("Phone进行充电...")p.v.Use5V()}//被适配的角色,适配者type V220 struct {}func (v *V220) Use220V() {fmt.Println("使用220V的电压")}//电源适配器type Adapter struct {v220 *V220}func (a *Adapter) Use5V() {fmt.Println("使用适配器进行充电")//调用适配者的方法a.v220.Use220V()}func NewAdapter(v220 *V220) *Adapter {return &Adapter{v220}}// ------- 业务逻辑层 -------func main() {iphone := NewPhone(NewAdapter(new(V220)))iphone.Charge()}
外观模式
package mainimport "fmt"type SubSystemA struct {}func (sa *SubSystemA) MethodA() {fmt.Println("子系统方法A")}type SubSystemB struct {}func (sb *SubSystemB) MethodB() {fmt.Println("子系统方法B")}type SubSystemC struct {}func (sc *SubSystemC) MethodC() {fmt.Println("子系统方法C")}type SubSystemD struct {}func (sd *SubSystemD) MethodD() {fmt.Println("子系统方法D")}//外观模式,提供了一个外观类, 简化成一个简单的接口供使用type Facade struct {a *SubSystemAb *SubSystemBc *SubSystemCd *SubSystemD}func (f *Facade) MethodOne() {f.a.MethodA()f.b.MethodB()}func (f *Facade) MethodTwo() {f.c.MethodC()f.d.MethodD()}func main() {//如果不用外观模式实现MethodA() 和 MethodB()sa := new(SubSystemA)sa.MethodA()sb := new(SubSystemB)sb.MethodB()fmt.Println("-----------")//使用外观模式f := Facade{a: new(SubSystemA),b: new(SubSystemB),c: new(SubSystemC),d: new(SubSystemD),}//调用外观包裹方法f.MethodOne()}
模板模式
package mainimport "fmt"//抽象类,制作饮料,包裹一个模板的全部实现步骤type Beverage interface {BoilWater() //煮开水Brew() //冲泡PourInCup() //倒入杯中AddThings() //添加酌料WantAddThings() bool //是否加入酌料Hook}//封装一套流程模板,让具体的制作流程继承且实现type template struct {b Beverage}//封装的固定模板func (t *template) MakeBeverage() {if t == nil {return}t.b.BoilWater()t.b.Brew()t.b.PourInCup()//子类可以重写该方法来决定是否执行下面动作if t.b.WantAddThings() == true {t.b.AddThings()}}//具体的模板子类 制作咖啡type MakeCaffee struct {template //继承模板}func NewMakeCaffee() *MakeCaffee {makeCaffe := new(MakeCaffee)//b 为Beverage,是MakeCaffee的接口,这里需要给接口赋值,指向具体的子类对象//来触发b全部接口方法的多态特性。makeCaffe.b = makeCaffereturn makeCaffe}func (mc *MakeCaffee) BoilWater() {fmt.Println("将水煮到100摄氏度")}func (mc *MakeCaffee) Brew() {fmt.Println("用水冲咖啡豆")}func (mc *MakeCaffee) PourInCup() {fmt.Println("将充好的咖啡倒入陶瓷杯中")}func (mc *MakeCaffee) AddThings() {fmt.Println("添加牛奶和糖")}func (mc *MakeCaffee) WantAddThings() bool {return true //启动Hook条件}//具体的模板子类 制作茶type MakeTea struct {template //继承模板}func NewMakeTea() *MakeTea {makeTea := new(MakeTea)//b 为Beverage,是MakeTea,这里需要给接口赋值,指向具体的子类对象//来触发b全部接口方法的多态特性。makeTea.b = makeTeareturn makeTea}func (mt *MakeTea) BoilWater() {fmt.Println("将水煮到80摄氏度")}func (mt *MakeTea) Brew() {fmt.Println("用水冲茶叶")}func (mt *MakeTea) PourInCup() {fmt.Println("将充好的咖啡倒入茶壶中")}func (mt *MakeTea) AddThings() {fmt.Println("添加柠檬")}func (mt *MakeTea) WantAddThings() bool {return false //关闭Hook条件}func main() {//1. 制作一杯咖啡makeCoffee := NewMakeCaffee()makeCoffee.MakeBeverage() //调用固定模板方法fmt.Println("------------")//2. 制作茶makeTea := NewMakeTea()makeTea.MakeBeverage()}
命令模式
package mainimport "fmt"//医生-命令接收者type Doctor struct {}func (d *Doctor) treatEye() {fmt.Println("医生治疗眼睛")}func (d *Doctor) treatNose() {fmt.Println("医生治疗鼻子")}//抽象的命令type Command interface {Treat()}//治疗眼睛的病单type CommandTreatEye struct {doctor *Doctor}func (cmd *CommandTreatEye) Treat() {cmd.doctor.treatEye()}//治疗鼻子的病单type CommandTreatNose struct {doctor *Doctor}func (cmd *CommandTreatNose) Treat() {cmd.doctor.treatNose()}//护士-调用命令者type Nurse struct {CmdList []Command //收集的命令集合}//发送病单,发送命令的方法func (n *Nurse) Notify() {if n.CmdList == nil {return}for _, cmd := range n.CmdList {cmd.Treat() //执行病单绑定的命令(这里会调用病单已经绑定的医生的诊断方法)}}//病人func main() {//依赖病单,通过填写病单,让医生看病doctor := new(Doctor)//治疗眼睛的病单cmdEye := CommandTreatEye{doctor}//治疗鼻子的病单cmdNose := CommandTreatNose{doctor}//护士nurse := new(Nurse)//收集管理病单nurse.CmdList = append(nurse.CmdList, &cmdEye)nurse.CmdList = append(nurse.CmdList, &cmdNose)//执行病单指令nurse.Notify()}
package mainimport "fmt"type Cooker struct {}func (c *Cooker) MakeChicken() {fmt.Println("烤串师傅烤了鸡肉串儿")}func (c *Cooker) MakeChuaner() {fmt.Println("烤串师傅烤了羊肉串儿")}//抽象的命令type Command interface {Make()}type CommandCookChicken struct {cooker *Cooker}func (cmd *CommandCookChicken) Make() {cmd.cooker.MakeChicken()}type CommandCookChuaner struct {cooker *Cooker}func (cmd *CommandCookChuaner) Make() {cmd.cooker.MakeChuaner()}type WaiterMM struct {CmdList []Command //收集的命令集合}func (w *WaiterMM) Notify() {if w.CmdList == nil {return}for _, cmd := range w.CmdList {cmd.Make()}}func main() {cooker := new(Cooker)cmdChicken := CommandCookChicken{cooker}cmdChuaner := CommandCookChuaner{cooker}mm := new(WaiterMM)mm.CmdList = append(mm.CmdList, &cmdChicken)mm.CmdList = append(mm.CmdList, &cmdChuaner)mm.Notify()}
策略模式
package mainimport "fmt"//武器策略(抽象的策略)type WeaponStrategy interface {UseWeapon() //使用武器}//具体的策略type Ak47 struct {}func (ak *Ak47) UseWeapon() {fmt.Println("使用Ak47 去战斗")}//具体的策略type Knife struct {}func (k *Knife) UseWeapon() {fmt.Println("使用匕首 去战斗")}//环境类type Hero struct {strategy WeaponStrategy //拥有一个抽象的策略}//设置一个策略func (h *Hero) SetWeaponStrategy(s WeaponStrategy) {h.strategy = s}func (h *Hero) Fight() {h.strategy.UseWeapon() //调用策略}func main() {hero := Hero{}//更换策略1hero.SetWeaponStrategy(new(Ak47))hero.Fight()hero.SetWeaponStrategy(new(Knife))hero.Fight()}
package mainimport "fmt"/*练习:商场促销有策略A(0.8折)策略B(消费满200,返现100),用策略模式模拟场景*///销售策略type SellStrategy interface {//根据原价得到售卖价GetPrice(price float64) float64}type StrategyA struct {}func (sa *StrategyA) GetPrice(price float64) float64 {fmt.Println("执行策略A, 所有商品打八折")return price * 0.8;}type StrategyB struct {}func (sb *StrategyB) GetPrice(price float64) float64 {fmt.Println("执行策略B, 所有商品满200 减100")if price >= 200 {price -= 100}return price;}//环境类type Goods struct {Price float64Strategy SellStrategy}func (g *Goods) SetStrategy(s SellStrategy) {g.Strategy = s}func (g *Goods) SellPrice() float64 {fmt.Println("原价值 ", g.Price , " .")return g.Strategy.GetPrice(g.Price)}func main() {nike := Goods{Price: 200.0,}//上午 ,商场执行策略Anike.SetStrategy(new(StrategyA))fmt.Println("上午nike鞋卖", nike.SellPrice())//下午, 商场执行策略Bnike.SetStrategy(new(StrategyB))fmt.Println("下午nike鞋卖", nike.SellPrice())}
观察者模式
package mainimport "fmt"//--------- 抽象层 --------//抽象的观察者type Listener interface {OnTeacherComming() //观察者得到通知后要触发的动作}type Notifier interface {AddListener(listener Listener)RemoveListener(listener Listener)Notify()}//--------- 实现层 --------//观察者学生type StuZhang3 struct {Badthing string}func (s *StuZhang3) OnTeacherComming() {fmt.Println("张3 停止 ", s.Badthing)}func (s *StuZhang3) DoBadthing() {fmt.Println("张3 正在", s.Badthing)}type StuZhao4 struct {Badthing string}func (s *StuZhao4) OnTeacherComming() {fmt.Println("赵4 停止 ", s.Badthing)}func (s *StuZhao4) DoBadthing() {fmt.Println("赵4 正在", s.Badthing)}type StuWang5 struct {Badthing string}func (s *StuWang5) OnTeacherComming() {fmt.Println("王5 停止 ", s.Badthing)}func (s *StuWang5) DoBadthing() {fmt.Println("王5 正在", s.Badthing)}//通知者班长type ClassMonitor struct {listenerList []Listener //需要通知的全部观察者集合}func (m *ClassMonitor) AddListener(listener Listener) {m.listenerList = append(m.listenerList, listener)}func (m *ClassMonitor) RemoveListener(listener Listener) {for index, l := range m.listenerList {//找到要删除的元素位置if listener == l {//将删除的点前后的元素链接起来m.listenerList = append(m.listenerList[:index], m.listenerList[index+1:]...)break}}}func (m* ClassMonitor) Notify() {for _, listener := range m.listenerList {//依次调用全部观察的具体动作listener.OnTeacherComming()}}func main() {s1 := &StuZhang3{Badthing: "抄作业",}s2 := &StuZhao4{Badthing: "玩王者荣耀",}s3 := &StuWang5{Badthing: "看赵四玩王者荣耀",}classMonitor := new(ClassMonitor)fmt.Println("上课了,但是老师没有来,学生们都在忙自己的事...")s1.DoBadthing()s2.DoBadthing()s3.DoBadthing()classMonitor.AddListener(s1)classMonitor.AddListener(s2)classMonitor.AddListener(s3)fmt.Println("这时候老师来了,班长给学什么使了一个眼神...")classMonitor.Notify()}
