设计模式学习与整理-模板方法模式

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

应用场景

 1、有多个子类共有的方法,且逻辑相同。

2、重要的、复杂的方法,可以考虑作为模板方法。

模式结构

1、抽象模板(Abstract Template):抽象模板是一个抽象类。抽象模板定义了若干个方法以表示算法的各个步骤,这些方法中有抽象方法也有非抽象方法,其中的抽象方法称为原语操作(Primitive Operation)。重要的一点是,抽象模板中还定义了一个称之为模板方法的方法,该方法不仅包含有抽象模板中表示算法步骤的方法调用,而且也可以包含有定义在抽象模板中的其他对象的方法调用,即模板方法定义了算法的骨架。

注意:一般模板方法都加上 final 关键词。

2、具体模板(Concrete Template):具体模板是抽象模板的子类,实现抽象模板中的原语操作。

下图中,描述了一个做饭的场景,cook() 方法为模板方法,cooking() 方法和 complete() 方法用于给子类重写。

代码案例

上图中做饭的场景,首先,有一个抽象方法:

public abstract class CookTemplate {

    public final void cook() {
        prepare();
        cooking();
        complete();
    }

    /**
     * 准备工作
     * */
    private void prepare() {
        System.out.println("准备好油盐酱醋。");
    }

    /**
     * 开始烹饪
     * */
    abstract void cooking();

    /**
     * 烹饪完成
     * */
    abstract void complete();
}

创建两个子类:

public class BouilliTemplate extends CookTemplate {

    @Override
    void cooking() {
        System.out.println("开始烧红烧肉。");
    }

    @Override
    void complete() {
        System.out.println("完成了红烧肉。");
    }
}

public class SoupTemplate extends CookTemplate {
    @Override
    void cooking() {
        System.out.println("开始烧汤。");
    }

    @Override
    void complete() {
        System.out.println("汤烧好了。");
    }
}

创建测试类

public class CookTemplateTest {

    public static void main(String[] args) {
        CookTemplate cook = new BouilliTemplate();
        cook.cook();
        System.out.println("---");
        CookTemplate cook2 = new SoupTemplate();
        cook2.cook();
    }
}

优点

1、封装不变部分,扩展可变部分。

2、提取公共代码,便于维护。

3、具体模板实现细节不会改变整个算法的框架。

缺点

每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。