JAVA 设计模式 模板方法模式

定义

模板方法模式(Template Method)

定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成。

模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模板方法模式是所有模式中最为常见的几个模式之一,是基于继承代码复用的基本技术。

因此,在模板方法模式的类结构图中,只有继承关系,没有关联关系。

模板方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。
代表这些具体逻辑步骤的方法称做基本方法(primitive method);而将这些基本方法汇总起来的方法叫做模板方法(template method),这个设计模式的名字就是从此而来。

// 范例

abstract class Template {
    
    public abstract void OperationA();
    
    public abstract void OperationB();
    
    public void TemplateMethod() {
        OperationB();
        OperationA();    
    }
    
}

class ConcreteA extends Template {

@Override
    public void OperationA() {
        System.out.println("ConcreteA OperationA()");
    }

@Override
    public void OperationB() {
        System.out.println("ConcreteA OperationB()");
    }
    
}

class ConcreteB extends Template {

@Override
    public void OperationA() {
        System.out.println("ConcreteB OperationA()");
    }

@Override
    public void OperationB() {
        System.out.println("ConcreteB OperationB()");
    }
    
}

public class TemplateMethodPattern {

public static void main(String[] args) {
        
        Template obj = null;
        
        obj = new ConcreteA();
        obj.TemplateMethod();
        
        obj = new ConcreteB();
        obj.TemplateMethod();
        
    }

}

// 运行结果

ConcreteA OperationB()
ConcreteA OperationA()
ConcreteB OperationB()
ConcreteB OperationA()

要点

模板方法模式中的三类角色

1、具体方法(Concrete Method)

2、抽象方法(Abstract Method)

3、钩子方法(Hook Method)

三类角色的关联

在模板方法模式中,首先父类会定义一个算法的框架,即实现算法所必须的所有方法。

其中,具有共性的代码放在父类的具体方法中。

各个子类特殊性的代码放在子类的具体方法中。但是父类中需要有对应抽象方法声明。

钩子方法可以让子类决定是否对算法的不同点进行挂钩。

总结

使用模板方法模式可以将代码的公共行为提取,以达到复用的目的。

而对于特殊化的行为在子类中实现。父类的模板方法可以控制子类中的具体实现。

子类无需了解整体算法框架,只需实现自己的业务逻辑即可。

实例

模板方法模式应用场景十分广泛。

在《Head First》的模板方法模式章节里列举了一个十分具有代表性的例子。

现实生活中,茶和咖啡是随处可见的饮料。冲泡一杯茶或冲泡一杯咖啡的过程是怎样的?

我们来整理一下流程。

泡茶:
烧开水 ==> 冲泡茶叶 ==> 倒入杯中 ==> 添加柠檬
泡咖啡:
烧开水 ==> 冲泡咖啡 ==> 倒入杯中 ==> 添加糖和牛奶

由以上处理步骤不难发现,准备这两种饮料的处理过程非常相似。我们可以使用模板类方法去限定制作饮料的算法框架。

其中相同的具有共性的步骤(如烧开水、倒入杯中),直接在抽象类中给出具体实现。

而对于有差异性的步骤,则在各自的具体类中给出实现。

//抽象类

abstract class Beverage {

// 模板方法,决定了算法骨架。相当于TemplateMethod()方法
    public void prepareBeverage() {
        boilWater();
        brew();
        pourInCup();
        if (customWantsCondiments())
        {
            addCondiments();
        }
    }
    
    // 共性操作,直接在抽象类中定义
    public void boilWater() {
        System.out.println("烧开水");
    }
    
    // 共性操作,直接在抽象类中定义
    public void pourInCup() {
        System.out.println("倒入杯中");
    }
    
    // 钩子方法,决定某些算法步骤是否挂钩在算法中
    public boolean customWantsCondiments() {
        return true;
    }
    
    // 特殊操作,在子类中具体实现
    public abstract void brew();
    
    // 特殊操作,在子类中具体实现
    public abstract void addCondiments();
    
}

// 具体类

class Tea extends Beverage {

@Override
    public void brew() {
        System.out.println("冲泡茶叶");
    }

@Override
    public void addCondiments() {
        System.out.println("添加柠檬");
    }
    
}

class Coffee extends Beverage {

@Override
    public void brew() {
        System.out.println("冲泡咖啡豆");
    }

@Override
    public void addCondiments() {
        System.out.println("添加糖和牛奶");
    }
    
}

// 测试代码

public static void main(String[] args) {
        
    System.out.println("============= 准备茶 =============");
    Beverage tea = new Tea();
    tea.prepareBeverage();
    
    System.out.println("============= 准备咖啡 =============");
    Beverage coffee = new Coffee();
    coffee.prepareBeverage();
    
}

// 运行结果

============= 准备茶 =============
烧开水
冲泡茶叶
倒入杯中
添加柠檬
============= 准备咖啡 =============
烧开水
冲泡咖啡豆
倒入杯中
添加糖和牛奶

时间: 2024-10-09 19:08:35

JAVA 设计模式 模板方法模式的相关文章

java设计模式 模板方法模式Template Method

设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样.项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因.

Java设计模式--模板方法模式

定义: 模板模式是一种行为设计模式,使用了JAVA的继承机制,在抽象类中定义一个模板方法,该方法引用了若干个抽象方法(由子类实现)或具体方法(子类可以覆盖重写).它的实现思路是,创建一个桩方法,并且定义一些步骤让子类来实现.模板方法定义了一个算法的执行步骤,或者说能够提供一种默认的实现,这种实现概括一部分子类或者全部子类的共同部分. 举一个例子帮助理解,假设提供一种造房子的算法.算法的步骤就是模拟造房子的过程:建地基.建支撑,最后添加墙和窗户 – 1. Fundation,2. Pillars,

设计模式 - 模板方法模式(template method pattern) JFrame 详解

模板方法模式(template method pattern) JFrame 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式(template method pattern), Java的JFrame使用模板方法模式, paint()是可以覆盖的方法,

设计模式 - 模板方法模式(template method pattern) Applet 详解

模板方法模式(template method pattern) Applet 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式(template method pattern), applet就是一个能够在网页上面执行的小程序, applet有很多钩子(

设计模式 - 模板方法模式(template method pattern) 排序(sort) 详解

模板方法模式(template method pattern) 排序(sort) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式的一个主要的应用是排序(sort)算法. 对象的排列方式并不是完全相同, 所以需要排序(sort)算法compareTo()

设计模式 - 模板方法模式(template method pattern) 详解

模板方法模式(template method pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy 模板方法模式(template method pattern): 在一个方法中定义一个算法的骨架, 而将一些步骤延迟到子类中. 模板方法使得子类可以在不改变算法结构的情况下, 重新定义算法中的某些步骤. 模板方法可以进行挂钩(hook), 钩子(hook)是一种被声明在抽象类中的方法, 但只有空的或者默认的实现. 钩子的存在, 可以让子类有能力

结合JDK源码看设计模式——模板方法模式

前言: 相信很多人都听过一个问题:把大象关进冰箱门,需要几步? 第一,把冰箱门打开:第二,把大象放进去:第三,把冰箱门关上.我们可以看见,这个问题的答案回答的很有步骤.接下来我们介绍一种设计模式--模板方法模式,你会发现,它与这个问题的答案实际上有很多共同之处. 一.定义 定义一个算法骨架,允许子类为一个或多个步骤提供实现.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤. 二.适用场景 一次性实现一个算法的不变的部分,将可变的行为留给子类实现 也就是将各子类中公共行为被提取

Java 设计模式 -- 复合模式之二

接着上文的鸭鸣例子:Java 设计模式 -- 复合模式之一 上文中,我们的鸭鸣实现了 装饰者模式  适配器模式  工厂模式的结合 现在,又需要进行改动了,上文,是可以统计一群鸭子的叫声,现在需要能够观察个别鸭子的行为 引入观察者模式: 任何想被观察的Quackable都必须实现下面的接口 public interface QuackObservable { public void registerObserver(Observer observer); public void notifyobs

一起学java设计模式--代理模式(结构型模式)

代理模式 应用软件所提供的桌面快捷方式是快速启动应用程序的代理,桌面快捷方式一般使用一张小图片来表示(Picture),通过调用快捷方式的run()方法将调用应用软件(Application)的run()方法.使用代理模式模拟该过程,绘制类图并编程实现. package ProxyPattern; interface Software { void run(); } class Application implements Software { public void run() { Syste