设计模式

模板方法模式

2020-03-08  本文已影响0人  GeekerLou

模板方法模式

含义概述

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

使用场景

当有一个业务有 N 个步骤( 模板 ),其中一部分步骤是永恒不变的,那么就将不变的这些步骤抽象到父类中,可能变化的步骤留给子类去实现。

组成元素

案例

  1. Servlet 中的模板方法:doGet()/doPost()/service()方法
  2. Arrays.sort() 方法,它要求对象实现 Comparable 接口

优缺点比较

模板方法模式是将子类中不变的部分抽象到父类,可变的部分由子类去实现。

  1. 优点
    封装不变公共代码,便于维护。可变部分的代码由子类自由决定,扩展性强。

  2. 缺点
    每新增一个不同的实现都需要增加一个子类,可能导致类数量变多,增加系统复杂性。

实例

Cook.java

public abstract class Cook {

    /**
     * 钩子的开关变量
     */
    protected boolean needBeforeCook = false;

    /**
     * 钩子的开关
     *
     * @return
     */
    protected boolean needBeforeCook() {
        System.out.println("===钩子函数被禁用===");
        return false;
    }

    /**
     * 钩子函数
     */
    public void beforeCook() {
    }


    public void open() {
        System.out.println("打开抽油烟机");
    }

    public void fire() {
        System.out.println("生火");
    }

    /**
     * 期望子类去实现
     */
    public abstract void doCook();

    public void outfire() {
        System.out.println("灭火");
    }

    public void close() {
        System.out.println("关闭抽油烟机");
        System.out.println("======收工=======");
    }

    /**
     * 使用final关键字,防止子类重写
     */
    public final void cook() {
        // 默认开启钩子函数
        if (this.needBeforeCook()) {
            this.beforeCook();
        }

        this.open();
        this.fire();
        this.doCook();
        this.outfire();
        this.close();
    }
}

CookMeat.java

/**
 * 炒肉
 */
public class CookMeat extends Cook {

    @Override
    public boolean needBeforeCook() {
        return true;
    }

    @Override
    public void beforeCook() {
        System.out.println("腌制");
    }

    @Override
    public void doCook() {
        System.out.println("红烧肉");
    }
}

CookVegatables.java

public class CookVegatables extends Cook {


    @Override
    public void doCook() {
        System.out.println("炒蔬菜");
    }
}

单元测试

import com.netease.learn.designPattern.templateMethod.Cook;
import com.netease.learn.designPattern.templateMethod.CookMeat;
import com.netease.learn.designPattern.templateMethod.CookVegatables;
import org.junit.Test;

public class TemplateMethodTest {

    @Test
    public void test1() {
        Cook cook = new CookMeat();
        cook.cook();
    }

    @Test
    public void test2() {
        Cook cook = new CookVegatables();
        cook.cook();
    }
}

参考资料

  1. 代码仓库-模板方法模式
上一篇 下一篇

猜你喜欢

热点阅读