您的位置:首页 > 其它

模板模式(Template Pattern)

2017-04-12 10:32 344 查看
模板模式:别给我打电话,我会打给你。

场景:使用模板模式实现泡茶和冲咖啡的两个类似行为。

//抽象基类作为模板

//以作为咖啡因饮品作为茶与咖啡的泛化类
public abstract class CaffeineBeverage
{
//提供唯一的准备饮品的方法
public void prepareRecipe()
{
//流程模板:烧水,冲泡,入杯,加调料
boilWater();
brew();
pourInCup();
if (customerWantsCondiments())
{
addCondiments();
}
}
//抽象方法:冲泡
protected abstract void brew();
//抽象方法:加调料
protected abstract void addCondiments();
//公共方法:将水烧沸腾
void boilWater()
{
Console.WriteLine("将水烧至沸腾");
}
//公共方法:将饮料导入杯中
void pourInCup()
{
Console.WriteLine("将饮料导入杯中");
}
//钩子方法:用户是否想加入调料
protected virtual bool customerWantsCondiments()
{
return true;
}
}

//实现模板的具体类
public class Coffee:CaffeineBeverage
{
protected override void brew()
{
Console.WriteLine("倒入速溶咖啡粉末,并搅拌");
}

protected override void addCondiments()
{
Console.WriteLine("加入奶精和方块糖");
}
//钩子函数实现:子类实现但仍然由父类去调用,而不是调用父类
protected override bool customerWantsCondiments()
{
string answer = getUserInput();
if (answer.Equals("y"))
{
return true;
}
else
{
return false;
}
}

private string getUserInput()
{
string answer = null;
Console.Write("您是否需要加入奶精和方块糖(y/n)?");
answer = Console.ReadLine();
return answer;
}
}
public class Tea : CaffeineBeverage
{
protected override void brew()
{
Console.WriteLine("倒入茶叶,浸泡");
}

protected override void addCondiments()
{
Console.WriteLine("加入柠檬");
}

protected override bool customerWantsCondiments()
{
string answer = getUserInput();
if (answer.Equals("y"))
{
return true;
}
else
{
return false;
}
}

private string getUserInput()
{
string answer = null;
Console.Write("您是否需要加入柠檬(y/n)?");
answer = Console.ReadLine();
return answer;
}
}


测试用例:
static void Main(string[] args)
{
CaffeineBeverage cafferneBeverage = null;
while (true)
{
Console.WriteLine("您需要一些咖啡因饮品,请选择具体饮品,按回车键确认:");
Console.WriteLine("1.一杯咖啡");
Console.WriteLine("2.一杯茶");
string answer = Console.ReadLine();
if (answer.Equals("1"))
{
cafferneBeverage = new Coffee();
}
else if (answer.Equals("2"))
{
cafferneBeverage = new Tea();
}
else
{
return;
}
cafferneBeverage.prepareRecipe();
Console.WriteLine("按您的要求,准备好了饮品!!\n");
}
}测试结果:



总结:

1.“模板方法”定义了算法的步骤,把这些步骤的实现延迟到子类。

2.模板方法模式为我们提供了一种代码复用的重要技巧。

3.模板方法的抽象类可以定义具体方法、抽象方法和钩子。

4.抽象方法由子类实现。

5.钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖它。

6.好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用低层模块。

7.你将在真实世界代码中看到模块方法模式的许多变体,不要期待他们全都是一眼就可以被你认出的。(如LIST的sort方法)

8.策略模式和模板方法模式都封装算法,一个用组合,一个用继承。

9.工厂方法是模板方法的一种特殊版本。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: