【设计模式】模板方法模式

losetowin 发布于:2016-11-2 22:56 分类:Java  有 3506 人浏览,获得评论 0 条 标签: 设计模式 模板方法 

本文地址:http://www.dutycode.com/shejimoshi_mobanfangfa_jieshao.html
除非注明,文章均为 www.dutycode.com 原创,欢迎转载!转载请注明本文地址,谢谢。
定义

定义一个操作中算法的框架,将一些步骤延迟到子类。使得子类可以不改变一个算法的结构,即可重定义该算法的某些步骤。
或者可以描述成:
定义一个算法的骨架,将一些实现步骤延迟到子类。不变的行为放到超类中,去除掉子类中的重复代码。

UML图

QQ20161102-0.png

使用场景

多个子类有公共的方法,并且逻辑基本相同时。
重构时,经常会使用到模板方法模式,将相同的方法抽出放到父类中,子类实现个性化。同时可以考虑使用钩子方法约束行为。
算法比较复杂或者重要时,可以交由父类实现核心算法,由子类实现具体的细节。

基础介绍

模板方法比较简单,仅仅用到了继承,但是确是一个比较常用的设计模式。尤其在重构的时候。
如UML图,AbstractClass叫做抽象模板,主要包括两部分:
第一部分是基本方法,也叫做基本操作,是由子类实现。一般是抽象方法。
第二部分是模板方法,一般是一个具体方法,实现对基本方法的一个拼装调度。完成固定的算法或者框架。

注:
一般情况下,模板方法会添加final,防止子类对其修改。

ConcreceteClass1叫做具体模板,它主要实现父类定义的一个或者多个抽象方法。从而使得父类定义的基本方法能够在子类中实现。

通用代码

/**
 * 抽象模板
 * 
 * @author dutycode@gmail.com
 * @website http://www.dutycode.com
 * @github https://github.com/losetowin
 * @copyright 使用时请保留本注释
 * @version 1.0.0
 * @date 2016年11月2日
 */
public abstract class AbstractClass {
/**
* 基本方法,抽象方法,交由子类实现
*/
protected abstract void stepOne();
/**
* 基本方法
*/
protected abstract void setTwo();
/**
* 模板方法,控制流程/算法
*/
public final void templeteMethod(){
this.stepOne();
this.setTwo();
}
}

/**
 * 具体模板
 * 
 * @author dutycode@gmail.com
 * @website http://www.dutycode.com
 * @github https://github.com/losetowin
 * @copyright 使用时请保留本注释
 * @version 1.0.0
 * @date 2016年11月2日
 */
public class ConceteClass1 extends AbstractClass {
@Override
protected void stepOne() {
System.out.println("This is in conceteClass1. StepOne");
}
@Override
protected void setTwo() {
System.out.println("This is in conceteClass1. StepTwo");
}
}

/**
 * 具体模板
 * 
 * @author dutycode@gmail.com
 * @website http://www.dutycode.com
 * @github https://github.com/losetowin
 * @copyright 使用时请保留本注释
 * @version 1.0.0
 * @date 2016年11月2日
 */
public class ConceteClass2 extends AbstractClass {
@Override
protected void stepOne() {
System.out.println("This is in conceteClass2. StepOne");
}
@Override
protected void setTwo() {
System.out.println("This is in conceteClass2. StepTwo");
}
}

/**
 * 场景类
 * 
 * @author dutycode@gmail.com
 * @website http://www.dutycode.com
 * @github https://github.com/losetowin
 * @copyright 使用时请保留本注释
 * @version 1.0.0
 * @date 2016年11月2日
 */
public class Client {
public static void main(String[] args) {
AbstractClass clazz1 = new ConceteClass1();
clazz1.templeteMethod();
AbstractClass clazz2 = new ConceteClass2();
clazz2.templeteMethod();
         }
}


注意事项

抽象模板中的方法尽量设计成protected的,符合迪米特法则。(迪米特法则含义:见百度百科
实现类若非必要,不要扩大父类的访问权限。

优缺点

优点:
封装不变部分,扩展可变部分,方便后续扩展。扩展时只需要在增加一个子类即可(主算法/框架不变的前提下)。
提取公共部分代码,放置于父类,方便维护。
主行为(算法/框架)由父类控制,子类仅负责实现,保证逻辑的唯一性。

缺点:
会增加代码的阅读难度。

扩展

钩子方法

版权所有:《攀爬蜗牛》 => 《【设计模式】模板方法模式
本文地址:https://www.dutycode.com/shejimoshi_mobanfangfa_jieshao.html
除非注明,文章均为 《攀爬蜗牛》 原创,欢迎转载!转载请注明本文地址,谢谢。