模板方法模式是一种强大的行为设计模式,广泛应用于软件开发中。它通过在超类中定义算法的框架,允许子类在不改变整体结构的情况下重写特定步骤。在本文中,将以 Go 语言为例,探讨模板方法模式在直播创建场景中的应用,展示如何利用这一设计模式简化代码、减少重复,并提高系统的可扩展性。通过对即时型直播和预约型直播的分析,本文将详细阐述模板方法模式的实际应用及其与其他设计模式的关系。
👉 点击查看《Go语言设计模式实战》系列文章目录
《Go语言设计模式实战》以 Go 语言为示例,详细解读编程开发中常见设计模式的实现,涵盖创建型、结构型和行为型设计模式。每篇文章通过具体的 Go 代码展示模式的实际应用,帮助读者深入理解设计模式的核心原理及其在软件开发中的最佳实践。以下是该系列文章的全部内容:
- Go语言设计模式实战:单例模式详解
- Go语言设计模式实战:原型模式详解
- Go语言设计模式实战:工厂方法模式详解
- Go语言设计模式实战:建造者模式详解
- Go语言设计模式实战:建造者模式详解
- Go语言设计模式实战:抽象工厂模式详解
- Go语言设计模式实战:享元模式详解
- Go语言设计模式实战:代理模式详解
- Go语言设计模式实战:外观模式详解
- Go语言设计模式实战:桥接模式详解
- Go语言设计模式实战:组合模式详解
- Go语言设计模式实战:装饰模式详解
- Go语言设计模式实战:适配器模式详解
- Go语言设计模式实战:责任链模式详解
- Go语言设计模式实战:中介者模式详解
- Go语言设计模式实战:命令模式详解
- Go语言设计模式实战:迭代器模式详解
- Go语言设计模式实战:备忘录模式详解
- Go语言设计模式实战:状态模式详解
- Go语言设计模式实战:观察者模式详解
- Go语言设计模式实战:模板方法模式详解
- Go语言设计模式实战:策略模式详解
- Go语言设计模式实战:访问者模式详解
什么是模板方法模式?
模板方法(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
模板方法模式与其他模式的关系
- 工厂方法模式 是模板方法模式的一种特殊形式。同时,工厂方法可以作为一个大型模板方法中的一个步骤。
- 模板方法基于继承机制:它允许你通过扩展子类中的部分内容来改变部分算法。策略模式基于组合机制:你可以通过对相应行为提供不同的策略来改变对象的部分行为。模板方法在类层次上运作,因此它是静态的。策略在对象层次上运作,因此允许在运行时切换行为。
总结
模板方法模式在处理那些步骤相同但具体实现不同的场景时非常有效。通过定义算法的框架并将变化的部分留给子类,可以提高代码的可维护性和可读性。