简单工厂模式
package main
import "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 Fruit
if 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 main
import "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 AbstractFactory
appleFac = new(AppleFactory)
//2-生产相对应的具体水果
var apple Fruit
apple = appleFac.CreateFruit()
apple.Show()
//需求2:需要一个具体的香蕉对象
//1-先要一个具体的香蕉工厂
var bananaFac AbstractFactory
bananaFac = new(BananaFactory)
//2-生产相对应的具体水果
var banana Fruit
banana = bananaFac.CreateFruit()
banana.Show()
//需求3:需要一个具体的梨对象
//1-先要一个具体的梨工厂
var pearFac AbstractFactory
pearFac = new(PearFactory)
//2-生产相对应的具体水果
var pear Fruit
pear = pearFac.CreateFruit()
pear.Show()
//需求4:需要一个日本的苹果?
}
抽象工厂
package main
import "fmt"
// ======= 抽象层 =========
type AbstractApple interface {
ShowApple()
}
type AbstractBanana interface {
ShowBanana()
}
type AbstractPear interface {
ShowPear()
}
//抽象工厂
type AbstractFactory interface {
CreateApple() AbstractApple
CreateBanana() AbstractBanana
CreatePear() 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 AbstractApple
apple = new(ChinaApple)
return apple
}
func (cf *ChinaFactory) CreateBanana() AbstractBanana {
var banana AbstractBanana
banana = new(ChinaBanana)
return banana
}
func (cf *ChinaFactory) CreatePear() AbstractPear {
var pear AbstractPear
pear = 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 AbstractApple
apple = new(JapanApple)
return apple
}
func (jf *JapanFactory) CreateBanana() AbstractBanana {
var banana AbstractBanana
banana = new(JapanBanana)
return banana
}
func (cf *JapanFactory) CreatePear() AbstractPear {
var pear AbstractPear
pear = 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 AbstractApple
apple = new(AmericanApple)
return apple
}
func (af *AmericanFactory) CreateBanana() AbstractBanana {
var banana AbstractBanana
banana = new(AmericanBanana)
return banana
}
func (af *AmericanFactory) CreatePear() AbstractPear {
var pear AbstractPear
pear = new(AmericanPear)
return pear
}
// ======== 业务逻辑层 =======
func main() {
//需求1: 需要美国的苹果、香蕉、梨 等对象
//1-创建一个美国工厂
var aFac AbstractFactory
aFac = new(AmericanFactory)
//2-生产美国苹果
var aApple AbstractApple
aApple = aFac.CreateApple()
aApple.ShowApple()
//3-生产美国香蕉
var aBanana AbstractBanana
aBanana = aFac.CreateBanana()
aBanana.ShowBanana()
//4-生产美国梨
var aPear AbstractPear
aPear = aFac.CreatePear()
aPear.ShowPear()
//需求2: 需要中国的苹果、香蕉
//1-创建一个中国工厂
cFac := new(ChinaFactory)
//2-生产中国苹果
cApple := cFac.CreateApple()
cApple.ShowApple()
//3-生产中国香蕉
cBanana := cFac.CreateBanana()
cBanana.ShowBanana()
}
单例模式
package main
import "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 main
import "fmt"
type singelton struct {}
var instance *singelton
func 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 main
import (
"fmt"
"sync"
)
//定义锁
var lock sync.Mutex
type singelton struct {}
var instance *singelton
func 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 main
import (
"fmt"
"sync"
"sync/atomic"
)
//标记
var initialized uint32
var lock sync.Mutex
type singelton struct {}
var instance *singelton
func 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 main
import (
"fmt"
"sync"
)
var once sync.Once
type singelton struct {}
var instance *singelton
func GetInstance() *singelton {
once.Do(func(){
instance = new(singelton)
})
return instance
}
func (s *singelton) SomeThing() {
fmt.Println("单例对象的某方法")
}
func main() {
s := GetInstance()
s.SomeThing()
}
代理模式
package main
import "fmt"
type Goods struct {
Kind string //商品种类
Fact bool //商品真伪
}
// =========== 抽象层 ===========
//抽象的购物主题Subject
type 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 Shopping
shopping = new(KoreaShopping) //具体的购买主题
//1-先验货
if g1.Fact == true {
fmt.Println("对[", g1.Kind,"]进行了辨别真伪.")
//2-去韩国购买
shopping.Buy(&g1)
//3-海关安检
fmt.Println("对[",g1.Kind,"] 进行了海关检查, 成功的带回祖国")
}
fmt.Println("---------------以下是 使用 代理模式-------")
var overseasProxy Shopping
overseasProxy = NewProxy(shopping)
overseasProxy.Buy(&g1)
overseasProxy.Buy(&g2)
}
package main
import "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 main
import "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 Phone
huawei = new(HuaWei)
huawei.Show() //调用原构件方法
fmt.Println("---------")
//用贴膜装饰器装饰,得到新功能构件
var moHuawei Phone
moHuawei = NewMoDecorator(huawei) //通过HueWei ---> MoHuaWei
moHuawei.Show() //调用装饰后新构件的方法
fmt.Println("---------")
var keHuawei Phone
keHuawei = NewKeDecorator(huawei) //通过HueWei ---> KeHuaWei
keHuawei.Show()
fmt.Println("---------")
var keMoHuaWei Phone
keMoHuaWei = NewMoDecorator(keHuawei) //通过KeHuaWei ---> KeMoHuaWei
keMoHuaWei.Show()
}
适配器模式
package main
import "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 main
import "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 *SubSystemA
b *SubSystemB
c *SubSystemC
d *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 main
import "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 = makeCaffe
return 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 = makeTea
return 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 main
import "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 main
import "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 main
import "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{}
//更换策略1
hero.SetWeaponStrategy(new(Ak47))
hero.Fight()
hero.SetWeaponStrategy(new(Knife))
hero.Fight()
}
package main
import "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 float64
Strategy 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,
}
//上午 ,商场执行策略A
nike.SetStrategy(new(StrategyA))
fmt.Println("上午nike鞋卖", nike.SellPrice())
//下午, 商场执行策略B
nike.SetStrategy(new(StrategyB))
fmt.Println("下午nike鞋卖", nike.SellPrice())
}
观察者模式
package main
import "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()
}