系统架构设计——设计模式之模板模式

假如生活欺骗了你,请不要抱怨。他一定是在考验你,你要经得住考验。毕竟牛逼的人生不可能总是风平浪静。——写给自己。

一、模板模式定义

定义一个操作中的算法的骨架,而将步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤。——《设计模式:可复用面向对象设计软件的基础》

二、应用场景

对于代码有洁癖的人,绝不会容许一段代码被许多个方法重复使用。那我们我们怎么才能在许多个方法中抽取重复的代码,保留独有的呢?这就可以使用模板模式。它是一种面对方法的代码复用模板。

三、结构图

这里写图片描述

四、代码表示

在我们测试的时候,经常会测试一段代码的执行时间,具体的方法就是在执行这块代码之前后之后分别计算一下当前的毫秒时间,然后将二者相减就可以得到执行时间。那么其实执行代码的前后获取时间属于可复用的代码。在这里,我将用本人的开源小框架XCParse(还没有正式发布)进行执行效率测试。

4.1 模板类,TimeAbstract

package com.muxiaocao;

/**
 * 模板模式抽象类
 * com.muxiaocao TimeAbstract.java
 * @author muxiaocao {http://www.muxiaocao.cn}
 * @github {https://github.com/MuXiaoCao}
 * @time 2016年7月24日
 */
abstract class TimeAbstract {

    public abstract void testCode();

    public long getTime() {

        long start = System.currentTimeMillis();
        testCode();
        long end = System.currentTimeMillis();
        return end-start;
    }

}

4.2 具体模板实现类,FastJson和XCParse

package com.muxiaocao;

import com.alibaba.fastjson.JSON;
import com.fanglv.XCParse.otherparse.Bean;
/**
 * 模板抽象类的子类,实现了指定抽象方法
 * com.muxiaocao FastJson.java
 * @author muxiaocao {http://www.muxiaocao.cn}
 * @github {https://github.com/MuXiaoCao}
 * @time 2016年7月24日
 */
public class FastJson extends TimeAbstract{

    @Override
    public void testCode() {
        String json = "{\"age\":25,\"name\":\"muxiaocao\"}";
        JSON.parseObject(json, Bean.class);
    }

}
package com.muxiaocao;

import com.fanglv.XCParse.otherparse.Bean;
import com.fanglv.XCParse.parse.RecordParser.CallBack;
import com.fanglv.XCParse.parse.impl.RecordParserImpl;

/**
 * 模板抽象类的子类,实现了指定抽象方法
 * com.muxiaocao FastJson.java
 * @author muxiaocao {http://www.muxiaocao.cn}
 * @github {https://github.com/MuXiaoCao}
 * @time 2016年7月24日
 */
public class XCParse extends TimeAbstract{

    @Override
    public void testCode() {
        String parseString = "25,muxiaocao";
        RecordParserImpl<Bean> parser = new RecordParserImpl<Bean>(Bean.class);
        parser.parse(parseString, ",",new CallBack() {

            @Override
            public String DataDeal(int itemId, String data) {
                if (data.equals("muxiaocao")) {
                    return "xiaocao";
                }else {
                    return data;
                }
            }

        });
    }

}

4.3 测试类

package com.muxiaocao;

public class TestMain {

    public static void main(String[] args) {
        TimeAbstract fastJson = new FastJson();
        TimeAbstract xcParse = new XCParse();
        int number = 1000; // 执行1000次
        System.out.println("fastJson :" + fastJson.getTime(number));
        System.out.println("XCParse :" + xcParse.getTime(number));
    }
}

运行结果如下:

这里写图片描述

五、模板模式的认识

在以下情况下可以考虑使用模板方法模式:
(1) 对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。即:一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
(2) 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
(3) 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。

六、优缺点

优点:

  1. 在父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。

  2. 模板方法模式是一种代码复用技术,它在类库设计中尤为重要,它提取了类库中的公共行为,将公共行为放在父类中,而通过其子类来实现不同的行为,它鼓励我们恰当使用继承来实现代码复用。

  3. 可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特定步骤是否需要执行。

  4. 在模板方法模式中可以通过子类来覆盖父类的基本方法,不同的子类可以提供基本方法的不同实现,更换和增加新的子类很方便,符合单一职责原则和开闭原则。

缺点:

需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象,此时,可结合桥接模式来进行设计。

注意:转载请标明,转自itboy-木小草
尊重原创,尊重技术。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值