欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java-设计模式-第三篇-模板模式

程序员文章站 2022-06-15 20:09:39
...

本人所学设计模式皆出自于 结城浩先生的《图解设计模式》。

类图

    Java-设计模式-第三篇-模板模式  

为什么使用Template模式

        使用Template模式的优点是:由于在父类中的模板方法中编写了算法,因此无需在每个子类中再编写算法;列如:我们没有使用Temlpate模式,而使使用文本编辑器的复制粘贴编写了多个ConcreteClass。如果编写完立即发现bug还好,但是如果过了一段时间才发现第一个ConcreteClass中有bug,那么我们必须将这个bug解决后的代码映射到所有的ConcreteClass中才行。关于这一点,我们使用了Template模式,所以我们只要在模板中进行修改就可以解决问题。

举例代码

package com.qiang.base;

/**
 * 模板模式抽象类
 *
 * @author zhangxinqiang
 * @date 2018/3/11
 */
public abstract class AbstractClass {
    /**
     * 方法执行的开始时间
     */
    private long startTime;

    /**
     * 打印日志 表示开始执行了,并记录下开始时间
     */
    private void start() {
        startTime = System.currentTimeMillis();
        System.out.println("info:方法开始执行了");
    }

    /**
     * 打印日志 标识方法执行结束,并记录耗时
     */
    private void end() {
        System.out.println("info:方法执行完毕\r\n耗时: " + (System.currentTimeMillis() - startTime) + " 毫秒");
    }

    /**
     * 此类要做什么
     */
    public final void doSomething() {
        start();
        howToDo();
        end();
    }

    /**
     * 如何去做,交给子类实现,怎么做都行
     */
    public abstract void howToDo();
}

package com.qiang;

import com.qiang.base.AbstractClass;

import java.util.concurrent.TimeUnit;

/**
 * 具体要做事情的子类
 *
 * @author zhangxinqiang
 * @date 2018/3/11
 */
public class ConcreteClass1 extends AbstractClass {

    @Override
    public void howToDo() {
        System.out.println("走着上班");
        try {
            TimeUnit.SECONDS.sleep(2L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

package com.qiang;

import com.qiang.base.AbstractClass;

import java.util.concurrent.TimeUnit;

/**
 * 具体要做事情的子类
 *
 * @author zhangxinqiang
 * @date 2018/3/11
 */
public class ConcreteClass2 extends AbstractClass {
    @Override
    public void howToDo() {
        System.out.println("开车上班");
        try {
            TimeUnit.SECONDS.sleep(1L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
package com;

import com.qiang.ConcreteClass1;
import com.qiang.base.AbstractClass;
import com.qiang.ConcreteClass2;

/**
 * 模板模式测试类
 *
 * @author zhangxinqiang
 * @date 2018/3/11
 */
public class Test {
    public static void main(String[] args) {
        AbstractClass howToWork = new ConcreteClass1();
        howToWork.doSomething();
        System.out.println("===================");
        howToWork = new ConcreteClass2();
        howToWork.doSomething();
    }
}

结果

info:方法开始执行了
走着上班
info:方法执行完毕
耗时: 2005 毫秒
===================
info:方法开始执行了
开车上班
info:方法执行完毕
耗时: 1003 毫秒

总结

        这里我们可以发现,我们只需要修改父类中的start,end 方法就可以对所有的日志输出进行修改。具体怎么使用还是要到具体的项目中进行实践,这里只是最简单的一种方式。Template模式最精华的部分就在抽象类中。

思考

        为什么我把start,end两个方法定义为private的?

        为什么我吧doSomething方法定义为final的?

        为什么无法使用接口来扮演AbstractClass的角色呢?

(代码中使用了java8的类java.util.concurrent.TimeUnit)

相关标签: Template Method