模板方法模式

模板方法模式

定义:

       模板方法模式是在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

类图:

Java之模板方法模式

这里涉及到两种角色:

1.      抽象模板:

定义了一个或多个抽象操作,以便让子类实现。

定义了一个模板方法,给出了一个顶级逻辑骨架,组装了操作的逻辑步骤,子类不可改变。

2.      具体模板

一般有多个具体模板角色,每个模板处理不同的业务

每个具体模板都要继承抽象模板类,实现抽象方法。

核心:子类可以替换父类的可变部分,但是不可以修改模板方法的顶级逻辑。

 

模式中的方法:

1.      模板方法

定义在抽象类中,把基本方法和钩子方法组合起来的final方法,封装了不可变的逻辑行为。

一个抽象类可以有多个模板方法,而不限于1个。每个模板方法都可以调用任意多个具体方法。

2.      基本方法

基本方法分三种:

i 抽象方法:定义在父类中的方法,由子类实现

ii 具体方法:由父类声明并实现,一般是父类私有方法。不需要子类重写。

iii 钩子方法:由父类定义的普通方法,子类可以重写,也可以不重写。通常父类会给出一个空实现,作为方法的默认实现。

 

实例:

AbstractFridge:抽象类,定义模板方法

package com.mylearn.designmodel.template;

 

/**

 * Created by IntelliJ IDEA.

 * User: yingkuohao

 * Date: 13-9-29

 * Time: 下午4:43

 * CopyRight:360buy

 * Descrption:

 * 模板方法:主要是抽象出一个操作流程的骨架,然后把具体的逻辑放入到子类中去。

 * 场景:当一个流程的主要流程都相似,都是经过几步共同的操作,就可以先定义出所经历的步骤,然后把骨架流程写成一个

 * 方法,供客户端调用。把

 * To change this template use File | Settings | File Templates.

 */

public abstract class AbstractFridge {

 

    /**

     * 定义模板类的骨架,核心方法,相当于一个模板,描述好这个类及其子类要做一个什么事情,

     * 把公用的方法直接写好,如openDoor,closeDoor。

     * 把具体子类的方法抽象出来,让子类去实现,如pushSth。

     *

     * 注意,方法被声明为final,以免子类改进这个算法的顺序。

     * @param context

     */

    final void execute(Context context) {

 

        //step1: 打开冰箱门

        openDoor();

        //step2: 放入东西(大象,或者是其他)

        pushSth(context);

        System.out.println("这次放入冰箱的是:" + context.getName());

        //step3: 关上冰箱门

        closeDoor();

         if(hook()) {

             System.out.println("hookexecute");

         }

    }

 

    /**

     * 钩子方法,子类可以选择覆盖

     * @return

     */

    private boolean hook() {

        return true;  //To change body of created methods use File | Settings | File Templates.

    }

 

    /**

     * 私有方法,子类不可动

     */

    private void openDoor() {

        System.out.println("open the door of the fridge!");

    }

 

 

    /**

     * 抽象方法,子类必须实现:往冰箱里放东西

     */

    protected abstract void pushSth(Context context);

 

    private void closeDoor() {

        System.out.println("close the door of the fridge!");

    }

}

ElephantFridge:子类——装大象的冰箱

public class ElephantFridge extends AbstractFridge {

    @Override

    public void pushSth(Context context) {

        context.setName("elephant");

    }

}

EggFridge:子类——装鸡蛋的冰箱

public class EggFridge extends AbstractFridge {

    @Override

    public void pushSth(Context context) {

        context.setName("egg");

    }

}

Client:客户端信息

public class Client {

    public static void main(String args[]) {

        Context context = new Context();

 

        AbstractFridge abstractFridge = new ElephantFridge();

        abstractFridge.execute(context);

    }

}

Context: 上下文对象

public class Context {

    private String name;

 

    public Context(String name) {

        this.name = name;

    }

 

    public Context() {

 

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

}

 

要点:

1. 模板方法定义了算法的步骤,把这些步骤的实现延迟到子类。

2. 模板方法模式为我们提供了一种代码复用的重要技巧

3. 模板方法的抽象类可以定义具体方法、抽象方法和钩子。

4. 抽象方法由子类来实现。

5. 钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖它。

6. 为了防止子类改变模板方法中的算法,可以将模板方法声明为final。

7. 好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用低层模块。

8. 你将在真实世界代码中看到模板方法模式的许多变体,不要期待它们全都是一眼就可以被你认出的。

9. 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。

10. 工厂方法是模板方法的一种特殊版本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值