模板模式

我比较喜欢吃,但是自己不会做,每次想吃什么了就买了原料,然后很不熟练的收拾,然后:媳妇,做饭了,我给你准备好了;妈,做饭了,我给你切好菜了。哎,一种寄人篱下的感觉。但是我还是比较喜欢我老妈做的菜,因为我媳妇做的饭菜一般都很清淡。

我们来模拟一下我媳妇做菜的类,做菜的步骤有:准备原料、烹饪、开吃、刷盘子。看看我媳妇怎么做:

public class wife_cook {

public void Prepare() {

System.out.print("放开那棵菜,我来洗!\n");

}

public void Cook() {

System.out.print("放油,放盐,不放鸡精,不放辣椒!\n");

}

public void ClearAway() {

System.out.print("别动,我来刷盘子!\n");

}

}

 

应用场景场景很简单:

public class Client {

public static void main(String[] args) {

// TODO Auto-generated method stub

wife_cook cooker = new wife_cook();

cooker.Prepare();

cooker.Cook();

cooker.ClearAway();

}

}

 

偶尔老妈来我们家,给我做饭,这时候如果实现老妈做菜的类,要考虑到都是我洗菜和刷盘子,只不过做菜的方式有变化,考虑后面可能还有人给我做饭,出于开放-封闭原则,将做菜类抽象出来,实现如下方案:

厨师基类:

public abstract class Cooker {

public void Prepare() {

System.out.print("放开那棵菜,我来洗!\n");

}

public abstract void Cook();

public void ClearAway() {

System.out.print("别动,我来刷盘子!\n");

}

}

 

具体厨师:

public class Mother extends Cooker{

@Override

public void Cook() {

System.out.print("放油,放盐,放鸡精,多放辣椒!\n");

}

}

 

public class Wife extends Cooker{

@Override

public void Cook() {

System.out.print("放油,放盐,不放鸡精,不放辣椒!\n");

}

}

 

应用场景:

public class Client {

public static void main(String[] args) {

// TODO Auto-generated method stub

Cooker cooker = new Mother();//new Wife();

cooker.Prepare();

cooker.Cook();

cooker.ClearAway();

}

}

 

这样很大程度上已经对做菜进行了封装,但是大家会发现,两个人都会放油,放盐。那么,如果我后宫佳丽三千,你每实现一个具体的厨师,都要重复的实现放油,放盐。如果哪次你实现的过程中忘记放油了,那么这个厨师做出来的菜肯定就没法吃了,估计吃完了你也不想刷盘子。也就是说,放油、放盐这些操作是相同的甚至是不可或缺的。这个时候我们可以使用模板模式。

 

模板模式:定义一个算法的骨架,将一些步骤延迟到子类中去实现,使得子类在不改变算法结构的前提下即可重定义该算法的某些特定步骤。

 

一、特征

1、骨架:在基类中实现算法的结构流程以及相同的步骤,这样充分的对该算法进行抽象,达到复用的目的。

2、延迟:骨架类创建一些虚函数,用于子类派生并实现重定义的步骤。骨架类在算法中以一定的逻辑结构调用这些虚函数并实现那些相同的步骤,从而达到实现该算法的目的;派生类重新实现骨架类的虚函数来重定义这些步骤即可。这样在应用场景中使用基类引用即可实现多态效果。

 

二、实现

抽象父类(AbstractClass):实现了模板方法,定义了算法的骨架。

具体类(ConcreteClass):实现抽象类中的抽象方法,即不同的对象的具体实现细节。

 

我们来看看如何使用模板模式重新实现做菜这件事儿:

创建算法骨架:

public abstract class TemplateCooker {

public void Prepare() {

System.out.print("放开那棵菜,我来洗!\n");

}

public void Cook()

{

System.out.print("放油,放盐,");

AddSeasoning();

}

public void ClearAway() {

System.out.print("别动,我来刷盘子!\n");

}

protected abstract void AddSeasoning();

}

 

具体厨师:

public class TemplateMother extends TemplateCooker{

@Override

protected void AddSeasoning() {

System.out.print("放鸡精,多放辣椒!\n");

}

}

 

public class TemplateWife extends TemplateCooker{

@Override

protected void AddSeasoning() {

System.out.print("不放鸡精,不放辣椒!\n");

}

}

 

应用场景:

public class Client {

public static void main(String[] args) {

// TODO Auto-generated method stub

TemplateCooker cooker = new TemplateWife();//new TemplateMother();

cooker.Prepare();

cooker.Cook();

cooker.ClearAway();

}

}

 

这样可以最大限度地进行代码复用,同时使得代码易维护,易扩展;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值