首页 > 其他 > 详细

设计模式 9 —— 模板方法模式

时间:2015-09-24 16:04:42      阅读:315      评论:0      收藏:0      [点我收藏+]

设计模式目录:

设计模式 1 ——观察者模式

设计模式 2 —— 装饰者模式 

设计模式 3 —— 迭代器和组合模式(迭代器)

设计模式 4 —— 迭代器和组合模式(组合)

设计模式 5 —— 工厂模式

设计模式 6 —— 单件模式

设计模式 7 —— 命令模式

设计模式 8 —— 适配器和外观模式

设计模式 9 —— 模板方法模式

 

模板模式是一种行为设计模式,它的实现思路是,创建一个桩方法,并且定义一些步骤让子类来实现。模板方法定义了一个算法的执行步骤,或者说能够提供一种默认的实现,这种实现概括一部分子类或者全部子类的共同部分。

举一个例子帮助理解,假设提供一种造房子的算法。算法的步骤就是模拟造房子的过程:建地基、建支撑,最后添加墙和窗户 – 1. Fundation,2. Pillars,3. Walls,4. Windows。最重要的一点就是不能改变此建造过程,比如不可能在没用地基的时候就开始建造窗户。这个例子中,我们就创建了一个模板方法 – 将使用不同的方法完成对房子的建造。

为了确保子类不能重写(override)这个模板方法,应当使用final

模板方法抽象类

因为设计为一些方法的具体实现留待子类中,所以不得不安排基类为一个抽象类

HouseTemple.java

 1 package cn.telling.test.action;
 2 
 3 /**
 4  * 
 5  * @ClassName: HouseTemplate TODO
 6  * @author xingle
 7  * @date 2015-9-24 下午2:04:22
 8  */
 9 public abstract class HouseTemplate {
10     // template method, final so subclasses can‘t override
11     public final void buildHouse() {
12         buildFoundation();
13         buildPillars();
14         buildWalls();
15         buildWindows();
16         System.out.println("House is built.");
17     }
18 
19     // default implementation
20     private void buildWindows() {
21         System.out.println("Building Glass Windows");
22     }
23 
24     // methods to be implemented by subclasses
25     public abstract void buildWalls();
26 
27     public abstract void buildPillars();
28 
29     private void buildFoundation() {
30         System.out.println("Building foundation with cement,iron rods and sand");
31     }
32 
33 }

 

buildHouse()是模板方法并定义了在建造房子过程中一系列方法的执行顺序。

WoodenHouse.java

 1 package cn.telling.test.action;
 2 
 3 /**
 4  * 
 5  * @ClassName: WoodenHouse
 6  * TODO
 7  * @author xingle
 8  * @date 2015-9-24 下午2:07:06
 9  */
10 public class WoodenHouse extends HouseTemplate{
11 
12     /**
13      * 
14      * @Description: TODO
15      * @author xingle
16      * @data 2015-9-24 下午2:07:15
17      */
18     @Override
19     public void buildWalls() {
20         System.out.println("Building Wooden Walls");
21         
22     }
23 
24     /**
25      * 
26      * @Description: TODO
27      * @author xingle
28      * @data 2015-9-24 下午2:07:15
29      */
30     @Override
31     public void buildPillars() {
32         System.out.println("Building Pillars with Wood coating");
33     }
34 
35 }

 

此处也应当对其他方法进行重写,但是为了简便,此处没用完成。

GlassHouse.java

 1 package cn.telling.test.action;
 2 
 3 /**
 4  * 
 5  * @ClassName: GlassHouse
 6  * TODO
 7  * @author xingle
 8  * @date 2015-9-24 下午2:05:28
 9  */
10 public class GlassHouse extends HouseTemplate{
11 
12     /**
13      * 
14      * @Description: TODO
15      * @author xingle
16      * @data 2015-9-24 下午2:05:39
17      */
18     @Override
19     public void buildWalls() {
20         System.out.println("Building Glass Walls");
21     }
22 
23     /**
24      * 
25      * @Description: TODO
26      * @author xingle
27      * @data 2015-9-24 下午2:05:39
28      */
29     @Override
30     public void buildPillars() {
31         System.out.println("Building Pillars with glass coating");
32         
33     }
34 
35 }

 

使用模板方法

用一个测试程序来测试此处已完成的模板方法。

HouseClient.java

 1 package cn.telling.test.action;
 2 
 3 /**
 4  * 
 5  * @ClassName: HousingClient TODO
 6  * @author xingle
 7  * @date 2015-9-24 下午2:06:33
 8  */
 9 public class HousingClient {
10     public static void main(String[] args) {
11 
12         HouseTemplate houseType = new WoodenHouse();
13 
14         // using template method
15         houseType.buildHouse();
16         System.out.println("************");
17 
18         houseType = new GlassHouse();
19 
20         houseType.buildHouse();
21     }
22 
23 }

 

注意,client正在调用基类的模板方法并且依赖于不同步骤的实现细节,即这些正在使用的方法,他们一些来着基类另一些来自子类。上述程序的输出:

技术分享

 

模板方法的UML图

技术分享

模板方法模式定义

模板方法模式定义一个操作中算法的骨架,而将这些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。

这个模式是用来创建一个算法的模板。什么是模板?如你所见的,模板就是一个方法。更具体地说,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现,这可以确保算法的结构保持不变,同时由子类提供部分实现。

JDK中模板方法模式的使用

  • java.io.InputStream, java.io.OutputStream, java.io.Reader 以及 java.io.Writer 中所有非抽象方法。
  • java.util.AbstractList, java.util.AbstractSet 以及 java.util.AbstractMap中所有非抽象方法。

重要提示

  • 模板方法应该是由确定的步骤组成。这些步骤的顺序是固定的。基类与子类之间某些方法或者实现可以有所不同。模板方法应该是final的。
  • 大多时候,子类的调用的方法是来自于超类。但是在模板模式中,超类的模板方法调用的方法却来至于子类,这就是著名的Hollywood原则-“don’t call us, we’ll call you”。
  • 基类方法的默认实现被退化为钩子Hooks的概念,他们被设计在子类中被重写,如果你期望一些方法在子类中不被重写,你可以让他们为final。比如在例子中buildFoundation()方法是final的,因为不希望它在子类中被重写。

 


参考:

  1. Java中的模板模式
  2. [Head First设计模式]云南米线馆中的设计模式——模版方法模式

设计模式 9 —— 模板方法模式

原文:http://www.cnblogs.com/xingele0917/p/4835190.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!