现在,我们要做一个番茄炒蛋,就下面这货:
这件事情我用程序实现下,先抽象一个做菜的模型:
publicabstractclassAbstractCook{/***做菜第一步就是先洗菜*/publicabstractvoidxicai();/***菜洗完了以后要切菜*/publicabstractvoidqiecai();/***然后就是起锅烧油,写到这的时候满脑子德子的声音*/publicabstractvoidqiguoshaoyou();/***菜烧好以后需要装盘就能上桌了*/publicabstractvoidzhuangpan();/***开始做菜*/publicabstractvoidcook();}然后开始番茄炒蛋:
publicclassTomatoEggsextendsAbstractCook{@Overridepublicvoidxicai(){System.out.println("番茄炒蛋先洗菜");}@Overridepublicvoidqiecai(){System.out.println("番茄炒蛋再切菜");}@Overridepublicvoidqiguoshaoyou(){System.out.println("现在开始起锅烧油做番茄炒蛋");}@Overridepublicvoidzhuangpan(){System.out.println("番茄炒蛋烧好以后装盘");}@Overridepublicvoidcook(){this.xicai();this.qiecai();this.qiguoshaoyou();this.zhuangpan();}}做完了番茄炒蛋,感觉有点不够吃,再来一个宫保鸡丁:
程序写到这里,好像有哪里不对,两个实现类的cook()方法都是完全相同的,那这个cook()方法的实现应该出现在抽象类,不应该在实现类上,抽象是所有子类的共性封装。
代码修改一下,把刚才做菜的那个抽象模型修改一下:
publicabstractclassAbstractCook{/***做菜第一步就是先洗菜*/publicabstractvoidxicai();/***菜洗完了以后要切菜*/publicabstractvoidqiecai();/***然后就是起锅烧油,写到这的时候满脑子德子的声音*/publicabstractvoidqiguoshaoyou();/***菜烧好以后需要装盘就能上桌了*/publicabstractvoidzhuangpan();/***开始做菜,在抽象类里直接定义执行过程*/publicvoidcook(){this.xicai();this.qiecai();this.qiguoshaoyou();this.zhuangpan();}}输出结果:
番茄炒蛋先洗菜番茄炒蛋再切菜现在开始起锅烧油做番茄炒蛋番茄炒蛋烧好以后装盘好了,这就是模版方法模式,是不是感觉很简单,经常会见到或者经常会用到。对的,没毛病,你经常在使用,但你不知道这是模板方法模式,
模板方法模式(TemplateMethodPattern):
Definetheskeletonofanalgorithminanoperation,deferringsomestepstosubclasses.TemplateMethodletssubclassesredefinecertainstepsofanalgorithmwithoutchangingthealgorithm'sstructure.(定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。)
在这张类图里面,AbstractClass叫做抽象模板,它的方法分为两类:
为了防止恶意的操作,一般模板方法都加上final关键字,不允许被覆写。
下面是模版方法模式的通用代码:
抽象模板类:
publicabstractclassAbstractClass{//基本方法protectedabstractvoiddoSomething();//基本方法protectedabstractvoiddoAnything();//模板方法publicfinalvoidtemplateMethod(){this.doSomething();this.doAnything();}}具体模板类:
publicclassConcreteClass1extendsAbstractClass{@OverrideprotectedvoiddoSomething(){//逻辑处理}@OverrideprotectedvoiddoAnything(){//逻辑处理}}publicclassConcreteClass2extendsAbstractClass{@OverrideprotectedvoiddoSomething(){//逻辑处理}@OverrideprotectedvoiddoAnything(){//逻辑处理}}