java设计模式之模板方法

在设计模式中模板方法其实挺好理解的,它将多个类中共同的逻辑抽象成一个模板方法,放在父类之中。

然后把实际场景中不确定的部分写成一个抽象方法,具体逻辑由子类实现,当然实际执行的时候模板方法调用的是子类中重新实现的方法。

这样就给父类中的模板方法实现了复用,而同时又给子类留下了扩展点。

模板方法的应用很多,Java Servlet、JUnit TestCase、Java InputStream、Java AbstractList的设计中都应用到了模板方法。

InputStream中read()方法就是一个模板方法,它需要调用另外一个同名的read()方法才能使用

AbstractList中的addAll()可以看做一个模板方法,他需要调用子类实现的add()方法。

HttpServlet 的 service() 函数也是一个模板方法,它需要调用同名的service()方法来实现功能,而同名service里再调用doGet/doPost等方法

Junit中的setUp/tearDown也是模板方法,先执行 setUp() 做些准备工作,然后执行 runTest() 运行真正的测试代码,最后执行 tearDown()扫尾。

 

我们写一个实际的例子,帮助大家理解。

java.util中有很多内置的容器类,大家都耳熟能详,那么他们的性能如何,你有测试过吗?初始化一个10000000的ArrayList和LinkedList哪个更快?

我们首先实现一个模板类,定义了元素个数和模板方法,统计初始化一个10000000元素的容器的耗时时长。

public abstract class Calculate {
    protected final int elementNum=10000000;

    /**
     * 统计method方法的时长
     */
    public final void templateMethod() {
        long s = System.currentTimeMillis();
        method();
        long e = System.currentTimeMillis();
        System.out.format("start->end=%d\n",e-s);
    }

    protected abstract void method();
    
}
public class ArrayCalculate extends Calculate {


    @Override
    protected void method() {
        System.out.println(this.getClass().getSimpleName());
        Integer[] integers = new Integer[elementNum];
        for (int i = 0; i < elementNum; i++) {
            integers[i] = i;
        }

    }
}

//
public class ArrayListCalculate extends Calculate {


    @Override
    protected void method() {
        System.out.println(this.getClass().getSimpleName());
        ArrayList<Integer> integers = new ArrayList<>();
        for (int i = 0; i < elementNum; i++) {
           integers.add(i);
        }
        integers.clear();
    }
}

//
public class LinkedListCalculate extends Calculate {


    @Override
    protected void method() {
        System.out.println(this.getClass().getSimpleName());
        List<Integer> integers = new LinkedList<>();
        for (int i = 0; i < elementNum; i++) {
           integers.add(i);
        }
        integers.clear();
    }
}

运行类

public class Main {
    public static void main(String[] args) {
        ArrayCalculate array = new ArrayCalculate();
        array.templateMethod();

        ArrayListCalculate arrayList = new ArrayListCalculate();
        arrayList.templateMethod();

        LinkedListCalculate linkedList = new LinkedListCalculate();
        linkedList.templateMethod();

        HashSetCalculate hashSet = new HashSetCalculate();
        hashSet.templateMethod();

        TreeSetCalculate treeSet = new TreeSetCalculate();
        treeSet.templateMethod();
    }
}

输出:

ArrayCalculate
start->end=2677
ArrayListCalculate
start->end=945
LinkedListCalculate
start->end=1044
HashSetCalculate
start->end=3028
TreeSetCalculate
start->end=2569

可以看出ArrayList相比原生数组还是有优势的!

posted @ 2022-01-25 09:55  Mars.wang  阅读(271)  评论(0编辑  收藏  举报