23种设计模式-模板方法模式
模板模式
简介
参考文档:https://en.wikipedia.org/wiki/Template_method_pattern
通常叫模板方法模式定义一个算法的骨架,并允许子类为一个或者多个步骤提供实现。
能够使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
属于行为性设计模式
适用场景
一次性实现一个算法的不变的部分,并将可变的部分交给子类来实现
各子类中公共的行为被提取出来并集中到一个公共的父类当中,从而避免代码重复
优点
1、利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。
2、将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。
3、把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,
符合开闭原则。
缺点
1、类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加。
2、类数量的增加,间接地增加了系统实现的复杂度。
3、继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍
案例
一个小偷偷东西一般分成几个步骤:
- 寻找目标
- 迷惑目标
- 下手
所以我们先定义一个小偷
public class HalflingThief {
private StealingMethod method;
public HalflingThief(StealingMethod method) {
this.method = method;
}
public void steal() {
method.steal();
}
public void changeMethod(StealingMethod method) {
this.method = method;
}
}
因为小偷偷东西都是几个固定步骤,所以我们使用模板方法,但是下手的过程有多种方式,所以开放钩子steal方法
/**
*
* StealingMethod defines skeleton for the algorithm.
*
*/
public abstract class StealingMethod {
private static final Logger LOGGER = LoggerFactory.getLogger(StealingMethod.class);
protected abstract String pickTarget();
protected abstract void confuseTarget(String target);
protected abstract void stealTheItem(String target);
/**
* Steal
*/
public void steal() {
String target = pickTarget();
LOGGER.info("The target has been chosen as {}.", target);
confuseTarget(target);
stealTheItem(target);
}
}
撞击然后开溜
public class HitAndRunMethod extends StealingMethod {
private static final Logger LOGGER = LoggerFactory.getLogger(HitAndRunMethod.class);
@Override
protected String pickTarget() {
return "old goblin woman";
}
@Override
protected void confuseTarget(String target) {
LOGGER.info("Approach the {} from behind.", target);
}
@Override
protected void stealTheItem(String target) {
LOGGER.info("Grab the handbag and run away fast!");
}
}
偷偷摸摸的干活
-
public class SubtleMethod extends StealingMethod { private static final Logger LOGGER = LoggerFactory.getLogger(SubtleMethod.class); @Override protected String pickTarget() { return "shop keeper"; } @Override protected void confuseTarget(String target) { LOGGER.info("Approach the {} with tears running and hug him!", target); } @Override protected void stealTheItem(String target) { LOGGER.info("While in close contact grab the {}'s wallet.", target); } }
测试
/**
*
* Template Method defines a skeleton for an algorithm. The algorithm subclasses provide
* implementation for the blank parts.
* <p>
* In this example {@link HalflingThief} contains {@link StealingMethod} that can be changed. First
* the thief hits with {@link HitAndRunMethod} and then with {@link SubtleMethod}.
*
*/
public class App {
/**
* Program entry point
*
* @param args command line args
*/
public static void main(String[] args) {
HalflingThief thief = new HalflingThief(new HitAndRunMethod());
thief.steal();
thief.changeMethod(new SubtleMethod());
thief.steal();
}
}
源码中的提现
JDBCTemplate
获取连接和关闭链接都已经写好了
处理结果集的地方开放
模板和策略的区别:
模板子类能干预实现,但是基础流程已经定下来了
策略不能干预流程,实现方式只能去选择
代码地址:https://gitee.com/zzy0_0/learning/tree/master/src/main/java/cn/zzjson/design/template