模板方法(Template Method)模式是一种行为设计模式,它在超类中定义了一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤。
以直播场景中创建直播为例,我们有两种类型的创建方式:即时型直播和预约型直播。不过不管是即时型还是预约型,他们的处理步骤都是一样的:
- 校验当前用户是否有权限进行直播
- 对提交的直播基础信息(如房间名、简介、背景图等)进行风控检测
- 创建直播
- 保存直播信息到数据库
- 数据上报
以上步骤中,除了第 3 项“创建直播”的具体业务逻辑不一样,其他步骤都是相同的。在这类场景中,操作步骤固定,只是在具体某一个步骤业务逻辑上存在差异,这时我们就可以考虑使用模板方法模式。
模板方法模式建议将算法分解为一系列步骤,然后将这些步骤改写为方法,将重复代码提取到一个超类中,最后在 “模板方法” 中依次调用这些方法。步骤方法可以是抽象的,也可以有一些默认的实现。
示例代码:
package main
import (
"errors"
"fmt"
)
// 定义 Liver 接口,其中的方法即创建直播所需的相关步骤
type Liver interface {
CheckPermissons() error
CheckRiskContent() error
CreateLive() error
SaveInDB() error
PushMetric()
}
// 超类
type Live struct {
liver Liver
userid int64
title string
}
// 定义创建直播的“模板方法”
func (l *Live) DoCreate() error {
if err := l.liver.CheckPermissons(); err != nil {
return err
}
if err := l.liver.CheckRiskContent(); err != nil {
return err
}
if err := l.liver.CreateLive(); err != nil {
return err
}
if err := l.liver.SaveInDB(); err != nil {
return err
}
l.liver.PushMetric()
return nil
}
// 校验用户开播权限
func (l *Live) CheckPermissons() error {
fmt.Println("check permissions pass")
return nil
}
// 风控检测
func (l *Live) CheckRiskContent() error {
fmt.Println("check risk content pass")
return nil
}
// 创建直播 待子类实现的抽象方法
func (l *Live) CreateLive() error {
// 默认返回一个 error 来实现抽象方法,要求之类必须实现
return errors.New("not implement")
}
// 信息落库
func (l *Live) SaveInDB() error {
fmt.Println("save in db")
return nil
}
// 上报统计数据
func (l *Live) PushMetric() {
fmt.Println("push metric")
}
// 1...即时型直播实现类
type ImmediateLive struct {
Live
}
func (i *ImmediateLive) CreateLive() error {
fmt.Println("ImmediateLive: create live room")
return nil
}
// 2...预约型直播实现类
type ScheduledLive struct {
Live
}
func (i *ScheduledLive) CreateLive() error {
fmt.Println("ScheduledLive: check live start time is valid and create some delay tasks")
return nil
}
func main() {
var liver Liver
// 即时型直播
liver = &ImmediateLive{}
live := Live{
liver: liver,
}
live.DoCreate()
fmt.Println("------")
// 预约型直播
liver = &ScheduledLive{}
live = Live{
liver: liver,
}
live.DoCreate()
}
运行示例代码,输出结果:
check permissions pass
check risk content pass
ImmediateLive: create live room
save in db
push metric
------
check permissions pass
check risk content pass
ScheduledLive: check live start time is valid and create some delay tasks
save in db
push metric
模板方法模式与其他模式的关系:
- 工厂方法模式是模板方法模式的一种特殊形式。同时,工厂方法可以作为一个大型模板方法中的一个步骤。
- 模板方法基于继承机制:它允许你通过扩展子类中的部分内容来改变部分算法。策略模式基于组合机制:你可以通过对相应行为提供不同的策略来改变对象的部分行为。模板方法在类层次上运作,因此它是静态的。策略在对象层次上运作,因此允许在运行时切换行为。