设计模式:模板方法模式
一、前言
前面我们讲过了迭代器模式和适配器模式,对于这两个‘器’,我们要有深刻的理解,理解何以称得上‘器’,工具也,拿来让我们使用的,人类和动物的最大区别是使用工具,虽然我对这个不是很同意,但是工具的重要性是毫无争议的,善假于物才能走到更高的地方去。现在开始,我们好好地看一看设计模式,其实无外乎接口、抽象类、具体类,通过连接(聚合、组合、继承和派生)从而实现多态来达到高内聚、低耦合的设计原则,这些原理中,我们可以看到一些基本原则了,比如将实现交给子类,尽量不要动以前已经封装好的模块,超类对子类的使用权限(里式代换法则),代码要具有可扩展性等等,通过这些看似复杂而在大型工程中必不可少的东西,我们建造了一个个高楼大厦。而模板方法就是将实现具体的实现交给子类,而父类只是做一些全局的任务安排,子类和父类需要紧密的配合才能实现一个任务的功能,因为工作的紧密结合,我们在写代码的时候一定要做好注释,这样才能使得程序具有强健的可读性。
二、模板方法模式
模板,就是设定一种结构或者架构,然后后续的所有工作都是在这个架子上填充相应的内容。比如老师要统计同学们的兴趣爱好,实现会给同学们一张纸,规定了姓名、学号、年龄、性别、兴趣爱好等模式,然后同学们按照给定的内容进行填充,不同的人会有不同的填写结果,最后老师收回同学们的结果,如果发现还想统计其他的信息,只用在模式上加入新的一个属性,这样就可以了,如果不这样做,我们可以看到有的同学只写了姓名,有的只写了兴趣爱好等等,这样在以后的维护之中就非常的麻烦,因为信息非常的混乱,由此可见模板的重要性。其实生活中处处可以看到,比如一个公司的收据,发票的格式,一卡通的格式,银行账号的格式,厕所的设计,各种文件的格式,邮件的格式等等,这种模式、模型、格式、规定、设计原则落到具体化的时候就变成了模板,我们当且仅当按照模板的方式进行填充了,我们的信息才会被认可和理解。同样的我们思考在面向对象设计(OOD)中,我们的模板应该是在子类还是父类呢,根据继承的特性,我们知道子类具有父类的所有特征,并且可以有父类没有的方法,而反之不能,因此,父类就是最好的模板材料,那么我们在父类上面设计一些属性或者模式,让子类去实现和完成,并且在父类上面给出一种统一的处理某类事物的方法,这种方法中将属性或者模式有机的组合和拼接起来,就成为模板方法。比如我们在模板中定义了A,B,C三种方法,这三种方法就是规定,然后我们在父类上在定义一个方法Model,Model使用了A,B,C方法来实现现实生活中的某一件事情,任何对于A,B,C的实现都需要经过Model进行处理才能够完成相应的事务,因此,我们成这个Model方法为模板。之后我们的任务需要一定的改变,只需要在Model上面进行操作就能同步到子类上面了,加入子类有100个,这是非常方便的。
代码如下:
AbstractDisplay抽象类:
1 package zyr.dp.template; 2 3 public abstract class AbstractDisplay { 4 public abstract void open(); 5 public abstract void print(); 6 public abstract void close(); 7 public final void display(){ 8 open(); 9 print(); 10 close(); 11 } 12 }
CharDisplay实现类:
1 package zyr.dp.template; 2 3 public class CharDisplay extends AbstractDisplay { 4 5 String word; 6 CharDisplay(String word){ 7 this.word=word; 8 } 9 public void open() { 10 System.out.print("<<"); 11 } 12 13 public void print() { 14 System.out.print(word); 15 } 16 17 public void close() { 18 System.out.println(">>"); 19 } 20 21 }
StringDisplay实现类:
1 package zyr.dp.template; 2 3 public class StringDisplay extends AbstractDisplay { 4 5 String word; 6 int width; 7 8 StringDisplay(String word){ 9 this.word=word; 10 width=word.getBytes().length; 11 } 12 13 public void open() { 14 printString(); 15 } 16 17 public void print() { 18 for(int i=0;i<5;i++){ 19 System.out.print("|"); 20 System.out.print(word); 21 System.out.println("|"); 22 } 23 } 24 25 public void close() { 26 printString(); 27 } 28 29 private void printString(){ 30 System.out.print("#"); 31 for(int i=0;i<width;i++){ 32 System.out.print("*"); 33 } 34 System.out.println("#"); 35 } 36 37 }
Main类:
1 package zyr.dp.template; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 AbstractDisplay p=new CharDisplay("zyr"); 7 p.display(); 8 System.out.println("----------------"); 9 p=new StringDisplay("zyr"); 10 p.display(); 11 } 12 13 }
运行结果:
三、总结
因此说模板非常容易理解,使用起来也很简单,但是在工程中我们往往将模板与其他模式结合起来,因此我们要认清模板的本质,将具有相同操作的多种事物抽象出这些相同的操作,然后将这些操作有机的整合起来变成模板类,另外也要注意在模板方法的定义final表示此方法不能被继承和重写,这无疑是重要的,规定和法则不能被其他人所改变。在后面的工厂方法里,我们可以看到模板的应用,以及迭代器的影子。