模版方法模式是行为型设计模式,定义是在父类中定义处理流程的框架,在子类种实现具体处理。
了解了设计模式的核定义,那么我们就可以按照这个想法去实现一个事例来演示一下模版方法模式的使用场景跟方法。
场景
我们可以模拟一个完成的手机操作流程,从解锁 -> 打开微信发起转账给老婆 -> 支付验证,我们可以对这一系列操作合并在一起叫 微信转账。而IPhone7跟IPhone12的操作是有差别的,我们知道IPhone7是可以用TouchID解锁手机和微信支付验证的,而IPhone12用的是FaceID来完成解锁手机跟支付验证的。那么我们就用代码应用模版模式来实现一下。
基础类和接口
首先定义一个手机接口Phone,接口包含了解锁unlock,支付transfer,以及验证verification三个方法,这些方法都是私有的,不对外公开
// 手机接口,所有方法都是私有的,就像现实生活中我们不会通过输入命令调用系统底层接口。这些都是APP封装好的。
type Phone interface {
unlock()
transfer()
verification()
}
在定义一个微信接口Wechat,只定义一个我们需要用到的微信支付WechatPay()方法
// 微信接口
type Wechat interface {
// 微信有微信支付的功能,是对外公开的方法,会调用系统底层的接口
WechatPay()
}
再定义一个IPhone结构体类型,嵌入了Phone接口(Golang没有继承的概念),并定了两个方法,分别是创建一个IPhone对象的NewIPhone和微信支付WechatPay模版方法,在这里,模版方法WechatPay定义了处理微信支付的整个流程框架。
// 组合手机接口
type IPhone struct {
Wechat
Phone
}
// 因为Golang嵌入接口的特殊性,需要传入实现了嵌入接口的对象
func NewIPhone(phone Phone) *IPhone {
return &IPhone{Phone: phone}
}
// IPhone类型(可以理解为父类)需要实现模版方法,支付
func (p *IPhone) WechatPay() {
// 定义处理流程的框架,子类实现具体处理
p.Phone.unlock()
p.Phone.transfer()
}
接着定义两个嵌入了(Golang没有继承)IPhone类型的IPhone7和IPhone12,并且都实现Phone接口的所有方法,这里的IPhone7和IPhone12就是具体实现了解锁、转账、验证等功能的子类
iphone7的实现
// 只有TouchID的IPhone7
type IPhone7 struct {
IPhone
}
// 使用TouchID解锁
func (p *IPhone7) unlock() {
fmt.Println("TouchID验证通过,解锁手机成功!")
}
func (p *IPhone7) transfer() {
fmt.Println("发起微信转账,请完成支付验证")
p.verification()
}
// 使用TouchID验证
func (p *IPhone7) verification() {
fmt.Println("使用TouchID完成验证,转账成功!")
}
iphone12的实现
// 只有FaceID的IPhone12
type IPhone12 struct {
IPhone
}
// 使用FaceID解锁
func (p *IPhone12) unlock() {
fmt.Println("FaceID验证通过,解锁手机成功!")
}
func (p *IPhone12) transfer() {
fmt.Println("发起微信转账,请完成支付验证")
p.verification()
}
// 使用FaceID验证
func (p *IPhone12) verification() {
fmt.Println("使用FaceID完成验证,转账成功!")
}
测试
func main() {
fmt.Println("使用IPhone7微信支付")
iphone7 := NewIPhone(&IPhone7{})
iphone7.WechatPay()
fmt.Println("\n使用IPhone12微信支付")
iphone12 := NewIPhone(&IPhone12{})
iphone12.WechatPay()
}
运行结果

代码已上传Github:LyonNee/design_patterns_with_go: 基于Golang实现的设计模式代码 (github.com)


被折叠的 条评论
为什么被折叠?



