设计模式——模板模式
- 设计模式分为创建型、结构型、行为型三大类。
- 创建型设计模式主要解决“对象的创建”问题
- 比较常用的有单例模式和工厂模式,相关链接如下:
- 设计模式——单例模式
- 设计模式——工厂模式
- 结构型设计模式主要解决“类或对象的组合”问题
- 比较常用的有代理模式,装饰器模式,相关链接如下:
- 设计模式——代理模式
- 设计模式——装饰器模式
- 行为型设计模式主要解决的就是“类或对象之间的交互”问题
- 比较常用的有观察者模式,策略模式,模板模式
- 设计模式——观察者模式
- 设计模式——策略模式
- 设计模式——模板模式
目录
- 模式定义和使用场景
- 模式结构
- 模板模式优点?
- 模板模式缺点?
- 模板模式代码实现
1. 模式定义和使用场景
- 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构就可以重定义该算法的某些特定步骤。
- 主要解决一些方法通用,却在每一个子类都重新写了这一方法的场景。
- 使用场景:比如冲咖啡和冲茶叶,整体过程是相同的,但细节不同。
- 煮水 1. 煮水
- 冲泡咖啡 2. 冲泡茶叶
- 倒入杯中 3. 倒入杯中
- 加糖和牛奶 4. 加柠檬
2. 模式结构
- 策略模式包含如下角色:
a. Game: 抽象类,定义了算法的骨架
b. Cricket和Football:具体模板类
3. 模板模式优点?
- 封装不变部分,扩展可变部分。
- 提取公共代码,便于维护。
- 行为由父类控制,子类实现。
4. 模板模式缺点?
- 每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
5. 模板模式代码实现
1. C++代码实现
#include <iostream>
#include <vector>
using namespace std;
class DrinkTemplate {
public:
virtual void BoildWater() = 0;
virtual void Brew() = 0;
virtual void PourInCup() = 0;
virtual void AddSomeThing() = 0;
void Make() {
BoildWater();
Brew();
PourInCup();
AddSomeThing();
}
};
class Coffee : public DrinkTemplate {
public:
void BoildWater() {
cout << "煮山泉水" << endl;
}
void Brew() {
cout << "冲泡咖啡" << endl;
}
void PourInCup() {
cout << "咖啡倒入杯中" << endl;
}
void AddSomeThing() {
cout << "加糖,加奶..." << endl;
}
};
class Tea : public DrinkTemplate {
public:
void BoildWater() {
cout << "煮山泉水" << endl;
}
void Brew() {
cout << "冲泡茶叶" << endl;
}
void PourInCup() {
cout << "茶水倒入杯中" << endl;
}
void AddSomeThing() {
cout << "加柠檬..." << endl;
}
};
int main() {
DrinkTemplate *coffee = new Coffee();
coffee->Make();
DrinkTemplate *tea = new Tea();
tea->Make();
delete coffee;
coffee = nullptr;
cout << "-----------------" << endl;
delete tea;
tea = nullptr;
return 0;
}
煮山泉水
冲泡咖啡
咖啡倒入杯中
加糖,加奶...
-----------------
煮山泉水
冲泡茶叶
茶水倒入杯中
加柠檬...
2. Go代码实现
package main
import "fmt"
type DrinkImpl interface {
BoilWater()
Brew()
PourInCup()
AddSomeThing()
}
type MakeDrinkTemplate struct {
drink DrinkImpl
}
func (m *MakeDrinkTemplate) MakeDrink() {
m.drink.BoilWater()
m.drink.Brew()
m.drink.PourInCup()
m.drink.AddSomeThing()
}
type Coffer struct {
}
func (c *Coffer) BoilWater() {
fmt.Println("煮山泉水")
}
func (c *Coffer) Brew() {
fmt.Println("冲泡咖啡")
}
func (c *Coffer) PourInCup() {
fmt.Println("咖啡倒入杯中")
}
func (c *Coffer) AddSomeThing() {
fmt.Println("加糖,加奶...")
}
type Tea struct {
}
func (t *Tea) BoilWater() {
fmt.Println("煮山泉水")
}
func (t *Tea) Brew() {
fmt.Println("冲泡茶叶")
}
func (t *Tea) PourInCup() {
fmt.Println("茶叶倒入杯中")
}
func (t *Tea) AddSomeThing() {
fmt.Println("加柠檬...")
}
func main() {
m1 := &MakeDrinkTemplate{
drink: new(Coffer),
}
m1.MakeDrink()
fmt.Println("-----------------")
m2 := &MakeDrinkTemplate{
drink: new(Tea),
}
m2.MakeDrink()
}
煮山泉水
冲泡咖啡
咖啡倒入杯中
加糖,加奶...
-----------------
煮山泉水
冲泡茶叶
茶叶倒入杯中
加柠檬...