被说了很多遍的设计模式---模板方法模式
来源:互联网 发布:开淘宝店卖什么比较好 编辑:程序博客网 时间:2024/05/21 22:39
[把你的理性思维慢慢变成条件反射]
本文,我们讲介绍模板方法模式,文章主题结构与上文一致。惯例,先来看看我们示例工程的环境:
操作系统:win7 x64
其他软件:eclipse mars,jdk7
-------------------------------------------------------------------------------------------------------------------------------------
经典问题:
相似的多个过程处理方法,函数,事件等等。
思路分析:
要点一:过程处理的相似性。
要点二:过程处理的差异性。
示例工程:
错误写法(1):
创建ProcessA.java文件,具体内容如下:
package com.csdn.ingo.gof_Template;public class ProcessA {public void cp1() {System.out.println("concrete process 1");System.out.println("concrete process A");}public void cp2() {System.out.println("concrete process 2");System.out.println("concrete process A");}public void cp3() {System.out.println("concrete process 3");System.out.println("concrete process A");}}
创建ProcessB.java文件,具体内容如下:
package com.csdn.ingo.gof_Template;public class ProcessB {public void cp1() {System.out.println("concrete process 1");System.out.println("concrete process B");}public void cp2() {System.out.println("concrete process 2");System.out.println("concrete process B");}public void cp3() {System.out.println("concrete process 3");System.out.println("concrete process B");}}创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_Template;public class Window {public static void main(String[] args) {System.out.println("----------Process A-----------");ProcessA pa = new ProcessA();pa.cp1();pa.cp2();pa.cp3();System.out.println("----------Process B-----------");ProcessA pb = new ProcessA();pb.cp1();pb.cp2();pb.cp3();}}
错误原因:
对于ProcessA,ProcessB两个文件中的相似代码完全没有处理,导致客户端产生大量重复代码。违反“开闭原则”。
错误写法(2):
创建Process.java文件,具体内容如下:
package com.csdn.ingo.gof_Template.one;public class Process {public void cp1() {System.out.println("concrete process 1");}public void cp2() {System.out.println("concrete process 2");}public void cp3() {System.out.println("concrete process 3");}}创建ConcreteProcessA.java,ConcreteProcessB.java文件,具体内容如下:
package com.csdn.ingo.gof_Template.one;public class ConcreteProcessA extends Process{public void cp1(){super.cp1();System.out.println("concrete process A");}public void cp2(){super.cp2();System.out.println("concrete process A");}public void cp3(){super.cp3();System.out.println("concrete process A");}}创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_Template.one;public class Window {public static void main(String[] args) {System.out.println("----------ConcreteProcessA-----------");ConcreteProcessA pa = new ConcreteProcessA();pa.cp1();pa.cp2();pa.cp3();System.out.println("----------ConcreteProcessB-----------");ConcreteProcessB pb = new ConcreteProcessB();pb.cp1();pb.cp2();pb.cp3();}}
错误原因:
在第一种写法的基础上,虽然做出了适当的改进,但是,请各位看官仔细观察具体子类中的代码实现,我们发现其中还有一句输出语句。在输出语句中,除了字符A,B的不同,其他内容完全一致。因此,我们还需要进一步抽象。
推荐写法:
创建Process.java文件,具体内容如下:
package com.csdn.ingo.gof_Template.two;public class Process {public void cp1(){System.out.println("concrete process 1");System.out.println("concrete process:" + oper());}public void cp2(){System.out.println("concrete process 2");System.out.println("concrete process:" + oper());}public void cp3(){System.out.println("concrete process 3");System.out.println("concrete process:" + oper());}protected String oper() {return "";}}创建ConcreteProcessA.java,ConcreteProcessB.java文件,具体内容如下:
package com.csdn.ingo.gof_Template.two;public class ConcreteProcessB extends Process {@Overridepublic String oper() {return "B";}}创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_Template.two;public class Window {public static void main(String[] args) {System.out.println("----------ConcreteProcessA-----------");Process pa = new ConcreteProcessA();pa.cp1();pa.cp2();pa.cp3();System.out.println("----------ConcreteProcessB-----------");Process pb = new ConcreteProcessB();pb.cp1();pb.cp2();pb.cp3();}}
推荐原因:
在第二种写法的基础之上,我们再次将子类的部分内容进行抽象。结果,子类当中仅保留差异化的部分内容,实现最大程度的简化。模式总结:
标准UML结构图:
概念总结:
模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
组成部分:AbstractClass(抽象类),ConcreteClass(具体子类)。
模式功能扩展:
对于抽象类内部而言,可以存在三种类型的方法:
- 抽象方法:具体实现可由子类完成。
- 具体方法:在抽象类内部完成,供其他具体方法调用。
- 钩子方法:在抽象类中有两种实现方式:(作用:在模板方法模式中,由于面向对象的多态性,子类对象在运行时将覆盖父类对象,子类中定义的方法也将覆盖父类中定义的方法。因此,程序在运行时,具体子类的基本方法将覆盖父类中定义的基本方法,子类的钩子方法也将覆盖父类的钩子方法,从而可以通过在子类中实现的钩子方法对父类方法的执行进行约束,实现子类对父类行为的反向控制。)
- 布尔型函数:供过程中的某些操作进行过程判断。
- 空函数:交给具体子类完成。作用是:保证编译通过。
示例代码:
package com.csdn.ingo.gof_Template.three;public abstract class AbstractClass {//抽象方法public abstract void PrimitiveOperation1();public abstract void PrimitiveOperation2();//模板方法public void TemplateMethod(){PrimitiveOperation1();PrimitiveOperation2();PrimitiveOperation3();System.out.println("");}//具体方法public void PrimitiveOperation3(){if(isLast()){ ... }}//布尔型钩子方法public boolean isLast(){return true;}//空函数钩子方法public void emptyMethod(){}}
反思:
应用场景:
在一个复杂的算法,过程处理当中,存在固定不变的部分,有限范围的可变部分。并且,固定部分能够狗此案够出来,可变部分能够交给其子类来处理。
需要子类来决定父类当中的某个函数是否执行,实现子类对父类的反向控制。
优点:
父类当中定义过程执行的顺序,子类决定过程执行的细节。满足“单一职责原则”,“开闭原则”。
有效实现代码复用。方便抽象公共的行为,子类当中保留差异化。
能够实现有效的反向控制。
缺点:
对父类中的抽象方法,钩子方法。都需要实现相应的子类实现。有可能导致子类数量过多。
抽象层级可能多级存在,不易于学习与维护。
-------------------------------------------------------------------------------------------------------------------------------------
至此,被说了很多遍的设计模式---模板方法模式 结束
参考资料:
图书:《大话设计模式》
其他博文:http://blog.csdn.NET/lovelion/article/details/7563445
- 被说了很多遍的设计模式---模板方法模式
- 被说了很多遍的设计模式---策略模式
- 被说了很多遍的设计模式---装饰模式
- 被说了很多遍的设计模式---代理模式
- 被说了很多遍的设计模式---原型模式
- 被说了很多遍的设计模式---外观模式
- 被说了很多遍的设计模式---观察者模式
- 被说了很多遍的设计模式---状态模式
- 被说了很多遍的设计模式---适配器模式
- 被说了很多遍的设计模式---备忘录模式
- 被说了很多遍的设计模式---组合模式
- 被说了很多遍的设计模式---迭代器模式
- 被说了很多遍的设计模式---命令模式
- 被说了很多遍的设计模式---访问者模式
- 被说了很多遍的设计模式---工厂方法模式
- 被说了很多遍的设计模式---简单工厂模式
- 被说了很多遍的设计模式---建造者模式
- 被说了很多遍的设计模式---抽象工厂模式
- 大麦与小麦
- innodb的读写参数优化
- Android Activity启动流程源码全解析(1)
- Hibernate使用注意
- Java从入门到上天 — — 你不能错过的11本好书
- 被说了很多遍的设计模式---模板方法模式
- 单机版solr6.2.1搭建window
- 响应式设计中的 HTML5
- 【图文解说】基于飞思卡尔MC9S12XS的Flash擦除和写入操作
- 车辆违章查询API 封装
- iOS 解决使用Cell的复用导致视图重叠的问题
- 一个简单的hibernate连接oracle数据库例子
- 第八章上机练习1 自己做的
- linux安装多系统之后启动等待90秒的解决办法