模板方法模式是行为型模式中一种,他通常只需实现一个根方法即可,该方法规定了各个方法的执行顺序。这些方法中可以是各个子类共有的,也可以是每个子类不一样的,该模板方法是父类独有的,一般可以定义为final,可以防止子类进行重写

现在我们以造房子为例子,一般造房子都是以规定的顺序开工的,先打地基,再搭骨架,然后砌墙,最后上玻璃。其中地基是不同房子基本都是一样的,骨架有的可以是木头的,有的可以是砖块的,有的是玻璃,墙也是同样的。这里我们以玻璃房和木头房举例子,这两个子类都继承房子的基类(HouseTemplate),他们的buildPillars 和 buildWalls 方法是不同的,但是他们的建造顺序都是一样的,在HouseTemplate中的buildHouse中实现

其中为了父类中的模板方法不被子类重写,我们把该方法定义为 final 方法

Template Method Abstract Class

因为父类中有点方法是不需要实现的,模板方法又必须实现的,故将该类定义为 abstract class

HouseTemplate.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.walterlife.dp.TemplateMethodDP;

import org.apache.log4j.Logger;

public abstract class HouseTemplate {

private Logger logger = Logger.getLogger(HouseTemplate.class);

// template method, order is fioxed
// final so subclasses can not override it
public final void buildHouse() {
buildFoudation();
buildPillers();
buildWalls();
buildWindows();
}

public void buildWindows() {
logger.info("HouseTemplate build windows!!!");
}

public abstract void buildWalls();

public abstract void buildPillers();

public void buildFoudation() {
logger.info("HouseTemplate build foudation!!!");
}
}

buildHouse() 是模板方法,该方法定义了建造房子固定的顺序

Template Method Concrete Classes

这里我们只以 木头房和 玻璃房为例

WoodenHouse.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.walterlife.dp.TemplateMethodDP;

import org.apache.log4j.Logger;

public class WoodenHouse extends HouseTemplate {

private Logger logger = Logger.getLogger(HouseTemplate.class);

@Override
public void buildWalls() {
// TODO Auto-generated method stub
logger.info("build house with wooden walls!!!");
}

@Override
public void buildPillers() {
// TODO Auto-generated method stub
logger.info("build house with wooden pills!!!");
}
}

GlassHouse.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.walterlife.dp.TemplateMethodDP;

import org.apache.log4j.Logger;

public class GlassHouse extends HouseTemplate {

private Logger logger = Logger.getLogger(HouseTemplate.class);

@Override
public void buildWalls() {
// TODO Auto-generated method stub
logger.info("build house with glass walls!!!");
}

@Override
public void buildPillers() {
// TODO Auto-generated method stub
logger.info("build house with glass pills!!!");
}
}

Test Method

现在开始测试我们刚刚实现的模板方法模式 代码

1
2
3
4
5
6
7
8
public static void testTemplateMethod() {
HouseTemplate house = new WoodenHouse();
house.buildHouse();
logger.info("================================");

house = new GlassHouse();
house.buildHouse();
}

输出

1
2
3
4
5
6
7
8
9
2015-09-07 22:43:28 INFO  com.walterlife.dp.TemplateMethodDP.HouseTemplate buildFoudation:27 -> HouseTemplate build foudation!!!
2015-09-07 22:43:28 INFO com.walterlife.dp.TemplateMethodDP.WoodenHouse buildPillers:18 -> build house with wooden pills!!!
2015-09-07 22:43:28 INFO com.walterlife.dp.TemplateMethodDP.WoodenHouse buildWalls:12 -> build house with wooden walls!!!
2015-09-07 22:43:28 INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildWindows:19 -> HouseTemplate build windows!!!
2015-09-07 22:43:28 INFO com.walterlife.dp.App testTemplateMethod:24 -> ================================
2015-09-07 22:43:28 INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildFoudation:27 -> HouseTemplate build foudation!!!
2015-09-07 22:43:28 INFO com.walterlife.dp.TemplateMethodDP.GlassHouse buildPillers:18 -> build house with glass pills!!!
2015-09-07 22:43:28 INFO com.walterlife.dp.TemplateMethodDP.GlassHouse buildWalls:12 -> build house with glass walls!!!
2015-09-07 22:43:28 INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildWindows:19 -> HouseTemplate build windows!!!

留言