09-Go设计模式-模板方法模式

模板方法模式

示例代码
/*
模板方法模式


模板方法模式中的角色和职责
AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,
每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。
同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,
模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。
*/
package _0_template_method

import "fmt"

//=============================== 抽象类 ==============================================
//Beverage 抽象类,制作饮料,包裹一个模板的全部实现步骤
type Beverage interface {
	BoilWater() //煮开水
	Brew()      //冲泡
	PourInCup() //倒入杯中
	AddThings() //添加佐料

	WantAddThings() bool //是否加入佐料Hook
}

//template 封装一套流程模板,让具体的制作流程继承且实现
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
}

//------------------------------- 制作茶 --------------------------------------
//具体的模板子类 制作茶
type MakeTea struct {
	template
}

func NewMakeTea() *MakeTea {
	makeTea := new(MakeTea)

	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条件
}

测试代码
package _0_template_method

import (
	"testing"
)

func TestMakeCaffee(t *testing.T) {
	//制作一杯咖啡
	makeCoffee := NewMakeCaffee()
	makeCoffee.MakeBeverage()
}

func TestMakeTea(t *testing.T) {
	//制作茶
	makeTea := NewMakeTea()
	makeTea.MakeBeverage()
}

posted @ 2022-10-11 15:52  李成果  阅读(149)  评论(0编辑  收藏  举报