使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

有一家咖啡店, 供应咖啡和茶, 它们的工序如下:

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

咖啡:

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

茶:

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

可以看到咖啡和茶的制作工序是差不多的, 都是有4步, 其中有两步它们两个是一样的, 另外两步虽然具体内容不一样, 但是都做做的同一类工作.

现在问题也有了, 当前的设计两个类里面有很多重复的代码, 那么应该怎样设计以减少冗余呢?

初次尝试

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

把共有的方法放到父类里面, 把不同的方法放到子类里面.

父类里面有一个抽象的prepareRecipe()方法[翻译为准备烹饪方法/制作方法], 然后在不同的子类里面有不同的实现. 也就是说每个子类都有自己制作饮料的方法.

再仔细想想应该怎样设计

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

可以发现两个饮料的制作方法遵循了同样的算法:

把水烧开

用开水冲咖啡或茶

把冲开的饮料放到杯里

添加适当的调料

现在我们来抽像prepareRecipe()方法:

1.先看看两个饮料的差异:

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

两种饮料都有四道工序, 两个是完全一样的, 另外两个在具体的实现上是略有不同的, 但是还是同样性质的工序.

这两道不同的工序的本质就是冲饮料和添加调料, 所以prepareRecipe()可以这样写:

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

2. 把上面的方法放到超类里:

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

这个父类是抽象的, prepareRecipe()将会用来制作咖啡或者茶, 而且我不想让子类去重写这个方法, 因为制作工序(算法)是一定的.

只不过里面的第2部和第4部是需要子类自己来实现的. 所以brew()和addCondiments()是两个抽象的方法, 而另外两个方法则直接在父类里面实现了.

3. 最后茶和咖啡就是这个样子的:

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

 

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

我们做了什么?

我们意识到两种饮料的工序大体是一致的, 尽管某些工序需要不同的实现方法. 所以我们把这些饮料的制作方法归纳到了一个基类CaffeineBeverage里面.

CaffeineBeverage控制着整个工序, 第1, 3部由它自己完成, 第2, 4步则是由具体的饮料子类来完成.

初识模板方法模式

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

上面的需求种, prepareRecipe() 就是模板方法. 因为, 它首先是一个方法, 然后它还充当了算法模板的角色, 这个需求里, 算法就是制作饮料的整个工序.

所以说: 模板方法定义了一个算法的步骤, 并允许子类提供其中若干个步骤的具体实现.

捋一遍整个流程

1. 我需要做一个茶:

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

2. 然后调用茶的模板方法:

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

3. 在模板方法里面执行下列工序:

boildWater();

brew();

pourInCup();

addCondiments();

模板方法有什么好处?

不使用模板方法时:

咖啡和茶各自控制自己的算法.

饮料间的代码重复.

改变算法需要修改多个地方

添加新饮料需要做很多工作.

算法分布在了不同的类里面

使用模板方法后:

CaffeineBeverage这个父类控制并保护算法

父类最大化的代码的复用

算法只在一个地方, 改变算法也只需改变这个地方

新的饮料只需实现部分工序即可

父类掌握着算法, 但是依靠子类去做具体的实现.

模板方法定义

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppydj.html