美文网首页
论模板模式

论模板模式

作者: 行走的鸡汤哥 | 来源:发表于2019-04-06 00:26 被阅读0次

模板方法模式的实现方案比对

问题:模板方法模式的主要意义在于规范算法流程。标准的模板方法模式采用抽象类的实现方案。但规范流程更像是规范行为。而抽象类与接口相比,抽象类侧重于属性,接口侧重于行为。再者java8开始,接口中可以编写默认方法,因此模板方法模式可以采用抽象类和接口两种实现方案。那么到底哪种实现方案比较合适呢?

需求:按指定流程推送数据。流程如下:
从数据库中查询数据 ---> 封装数据 ---> 推送

标准模板方法模式的写法

抽象模板类(抽象类):规范数据的使用流程

/**
 * Created by r.x on 2019/4/5.
 * 抽象模板
 */
public abstract class Template<T> {

    /**
     * 数据使用流程:
     * 1、查库
     * 2、封装数据
     * 3、推送数据
     */
    public final void use() {
        List<T> list = queryDb();
        JSONObject json = packData(list);
        push(json);
    }

    /**
     * 从数据库查询数据
     *
     * @return
     */
    protected abstract List<T> queryDb();

    /**
     * 按要求 封装数据
     *
     * @param list
     * @return
     */
    protected abstract JSONObject packData(List<T> list);

    /**
     * 通用的数据推送方法
     * @param json
     */
    private void push(JSONObject json) {
        System.out.println(json);
    }
}

string的具体使用实现

/**
 * Created by r.x on 2019/4/5.
 * string的具体使用实现
 */
public class PushString extends Template<String> {

    @Override
    protected List<String> queryDb() {
        return Collections.singletonList("string");
    }

    @Override
    protected JSONObject packData(List<String> list) {
        StringJoiner joiner = new StringJoiner(",");
        list.forEach(joiner::add);
        JSONObject json = new JSONObject();
        json.put("type", "string");
        json.put("data", joiner.toString());
        return json;
    }
}

integer的具体使用实现

/**
 * Created by r.x on 2019/4/5.
 * integer的具体使用实现
 */
public class PushInteger extends Template<Integer> {

    @Override
    protected List<Integer> queryDb() {
        return Collections.singletonList(0);
    }

    @Override
    protected JSONObject packData(List<Integer> list) {
        JSONObject json = new JSONObject();
        json.put("type", "integer");
        json.put("data", list);
        return json;
    }
}

入口类:

/**
 * Created by r.x on 2019/4/5.
 * 入口类
 */
public class Demo {

    public static void main(String[] args) {
        Template<String> pushString = new PushString();
        pushString.use();

        Template<Integer> pushInteger = new PushInteger();
        pushInteger.use();
    }
}

输出结果

{"data":"string","type":"string"}
{"data":[0],"type":"integer"}

用接口的方式实现模板方法模式

抽象模板(接口)

/**
 * Created by r.x on 2019/4/5.
 * 抽象模板
 */
public interface ITemplate<T> {
    /**
     * 数据使用流程:
     * 1、查库
     * 2、封装数据
     * 3、推送数据
     */
    default void use() {
        List<T> list = queryDb();
        JSONObject json = packData(list);
        push(json);
    }

    /**
     * 从数据库查询数据
     *
     * @return
     */
    List<T> queryDb();

    /**
     * 按要求 封装数据
     *
     * @param list
     * @return
     */
    JSONObject packData(List<T> list);

    /**
     * 通用的数据推送方法
     * @param json
     */
    default void push(JSONObject json) {
        System.out.println(json);
    }
}

integer的具体使用实现

/**
 * Created by r.x on 2019/4/5.
 * integer的具体使用实现
 */
public class PushIntegerImpl implements ITemplate<Integer> {

    @Override
    public List<Integer> queryDb() {
        return Collections.singletonList(-1);
    }

    @Override
    public JSONObject packData(List<Integer> list) {
        JSONObject json = new JSONObject();
        json.put("type", "integer impl");
        json.put("data", list);
        return json;
    }
}

string的具体使用实现

/**
 * Created by r.x on 2019/4/6.
 * string的具体使用实现
 */
public class PushStringImpl implements ITemplate<String> {
    @Override
    public List<String> queryDb() {
        return Collections.singletonList("string impl");
    }

    @Override
    public JSONObject packData(List<String> list) {
        StringJoiner joiner = new StringJoiner(",");
        list.forEach(joiner::add);
        JSONObject json = new JSONObject();
        json.put("type", "string impl");
        json.put("data", joiner.toString());
        return json;
    }
}

入口类

/**
 * Created by r.x on 2019/4/5.
 * 入口类
 */
public class DemoImpl {

    public static void main(String[] args) {
        ITemplate<String> pushString = new PushStringImpl();
        pushString.use();

        ITemplate<Integer> pushInteger = new PushIntegerImpl();
        pushInteger.use();
    }
}

输出结果:

{"data":"string impl","type":"string impl"}
{"data":[-1],"type":"integer impl"}

那么从输出结果可以看出,采用接口的方式也是可以实现同样的效果的

抽象类与接口方案的比对

从以上对比可以看出,虽然接口方式也能实现模板方法模式,但接口中定义的方法完全暴露了,甚至连最重要的use()方法也被暴露了,因为子类可以覆盖接口中的默认方法,此时就失去了规范流程的意义了。因此,即使技术上可行,但也不推荐使用接口的实现方案。

相关文章

  • 论模板模式

    模板方法模式的实现方案比对 问题:模板方法模式的主要意义在于规范算法流程。标准的模板方法模式采用抽象类的实现方案。...

  • 11.8设计模式-模板模式-详解

    设计模式-模式模式 模板方法模式详解 模板方法模式在android中的实际运用 1.模板方法模式详解 2.模板方法...

  • 第5章 -行为型模式-模板方法模式

    一、模板方法模式的简介 二、模板方法模式的优点 三、模板方法模式的应用场景 四、模板方法模式的实例

  • 模板方法模式

    模板方法模式 模板方法模式的定义 模板方法模式(Template Method Pattern)是如此简单,以致让...

  • 设计模式系列-模板方法模式

    JAVA设计模式系列: 单例模式 观察者模式 模板方法模式 模板方法模式 定义 模板方法模式在一个方法中定义了算法...

  • 设计模式(行为型)-- 模板模式

    模板模式的原理与实现 模板模式,全称是模板方法设计模式,英文是 Template Method Design Pa...

  • 行为型-Template

    模板模式的原理与实现 模板模式,全称是模板方法设计模式,英文是 Template Method Design Pa...

  • 行为型 模板模式(文末有项目连接)

    1:模板方式解决的问题(先了解) 2:模板模式的原理与实现 3:模板模式核心代码 4:模板模式复用例子(Input...

  • 模板模式,也是解耦算法的吗?

    模板模式,和算法有什么关系呢? 模板模式,在什么场景使用呢? 模板模式(Template Pattern),定义一...

  • 模板方法模式

    一、模板方法模式介绍 二、模板方法模式代码实例

网友评论

      本文标题:论模板模式

      本文链接:https://www.haomeiwen.com/subject/gjlxiqtx.html