Java设计模式--模板模式

1 Template Pattern 模板模式

目的:一个抽象类公开定义了执行它的方法的方式/模板,让它的具体实现在子类中进行;
实现:关键逻辑在抽象类实现,其他步骤在子类实现。

1.该模式的场景:1)分工协作,2)公共代码和个性化代码分离 等;
2.在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序,而通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果;
3.为防止恶意操作,一般模板方法都加上 final 关键词。

2 实现

代码场景:莲湖公园中有很多儿童玩的给石膏娃娃上色的摊位。
石膏雕塑已经被老板做好,但上色这个任务就交给了各个小盆友。

2.1 代码实现

小猪佩奇石膏雕塑抽象类

public abstract class AbstractPlasterSculpture {

    public final void show() {
        //生产模型雕塑
        productPlasterSculpture();
        //給模型上色
        coloring();
    }

    public void productPlasterSculpture()
    {  
        System.out.println("找些薄的铁皮来,沿着泥塑的高点把铁片插进去"); 
        System.out.println("把石膏粉或水一遍一遍的洒在泥塑上面"); 
        System.out.println("等干了以后,把在插片处一点一点把几半石膏模分开"); 
        System.out.println("在石膏模具里面加点钢筋,缠上麻丝"); 
        System.out.println("干了以后再用凿子把磨具敲碎,这样一个石膏雕塑出炉了"); 
    }
    //给雕塑上色 子类来实现 不同的儿童不同的实现
    public abstract void coloring();
}

具体实现类:涂成红色的小猪佩奇

public class RedPeiQi extends AbstractPlasterSculpture {

    @Override
    public void coloring() {
        System.out.println("将小猪佩琦雕塑涂成了红色");
    }

}

具体实现类:涂成黑色的小猪佩奇

public class BlackPeiQi extends AbstractPlasterSculpture {

    @Override
    public void coloring() {
        System.out.println("将小猪佩琦雕塑涂成了黑色");
    }

}

2.2 涉及角色

(1) AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。

(2) ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

模式实现
在实现模板方法模式时,开发抽象类的软件设计师和开发具体子类的软件设计师之间可以进行协作。一个设计师负责给出一个算法的轮廓和框架,另一些设计师则负责给出这个算法的各个逻辑步骤。实现这些具体逻辑步骤的方法即为基本方法,而将这些基本方法汇总起来的方法即为模板方法,模板方法模式的名字也因此而来。

基本方法是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。

(1) 抽象方法:一个抽象方法由抽象类声明、由其具体子类实现。
(2)具体方法:一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。
(3) 钩子方法:一个钩子方法由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现(可使用 virtual关键字将其定义为虚函数),并以该空实现作为方法的默认实现,当然钩子方法也可以提供一个非空的默认实现。

在模板方法模式中,钩子方法有两类:第一类钩子方法可以与一些具体步骤“挂钩”,以实现在不同条件下执行模板方法中的不同步骤,这类钩子方法的返回类型通常是 boolean 类型的,这类方法名一般为 IsXXX(),用于对某个条件进行判断,如果条件满足则执行某一步骤,否则将不执行,如下代码片段所示:

……
//模板方法
public void TemplateMethod() 
{
    Open();
    Display();
    //通过钩子方法来确定某步骤是否执行
    if (IsPrint()) 
    {
        Print();
    }
}

//钩子方法
public bool IsPrint()
{
    return true;
}
……

在模板方法模式中,由于面向对象的多态性,子类对象在运行时将覆盖父类对象,子类中定义的方法也将覆盖父类中定义的方法,因此程序在运行时,具体子类的基本方法将覆盖父类中定义的基本方法,子类的钩子方法也将覆盖父类的钩子方法,从而可以通过在子类中实现的钩子方法对父类方法的执行进行约束,实现子类对父类行为的反向控制。

2.3 调用

调用者:

public class Client {
    public static void main(String[] args) {
        AbstractPlasterSculpture redPeiQi = new RedPeiQi();
        redPeiQi.show();
        System.out.println("------------------制作完毕-------------------");

        AbstractPlasterSculpture blackPeiQi = new BlackPeiQi();
        blackPeiQi.show();
        System.out.println("------------------制作完毕-------------------");
    }
}

结果:

找些薄的铁皮来,沿着泥塑的高点把铁片插进去
把石膏粉或水一遍一遍的洒在泥塑上面
等干了以后,把在插片处一点一点把几半石膏模分开
在石膏模具里面加点钢筋,缠上麻丝
干了以后再用凿子把磨具敲碎,这样一个石膏雕塑出炉了
将小猪佩琦雕塑涂成了红色
------------------制作完毕-------------------
找些薄的铁皮来,沿着泥塑的高点把铁片插进去
把石膏粉或水一遍一遍的洒在泥塑上面
等干了以后,把在插片处一点一点把几半石膏模分开
在石膏模具里面加点钢筋,缠上麻丝
干了以后再用凿子把磨具敲碎,这样一个石膏雕塑出炉了
将小猪佩琦雕塑涂成了黑色
------------------制作完毕-------------------

代码地址:点击跳转

参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.

猜你喜欢

转载自blog.csdn.net/weixx3/article/details/80202252