博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
结合JDK源码看设计模式——模板方法模式
阅读量:5951 次
发布时间:2019-06-19

本文共 2562 字,大约阅读时间需要 8 分钟。

前言:

  相信很多人都听过一个问题:把大象关进冰箱门,需要几步?

  第一,把冰箱门打开;第二,把大象放进去;第三,把冰箱门关上。我们可以看见,这个问题的答案回答的很有步骤。接下来我们介绍一种设计模式——模板方法模式,你会发现,它与这个问题的答案实际上有很多共同之处。

一、定义

  定义一个算法骨架,允许子类为一个或多个步骤提供实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。

二、适用场景

  一次性实现一个算法的不变的部分,将可变的行为留给子类实现

  也就是将各子类中公共行为被提取出来并集中到一个公共父类中,从而避免代码重复。还是拿上面大象放进冰箱里面的例子,打开冰箱和关上冰箱都是不变的行为,我们可以将其放在公共父类实现。但是放大象,怎么放?是先放背对着冰箱放,还是面对着冰箱放。不想放大象,放老虎或者其他动物呢?这些就是我们可变的行为,这个就放入子类中实现。可以说,模板方法提供了一个很好的代码复用平台

三、JDK中的模板方法模式

  

  在刚接触ArrayList的时候一直没注意它继承的类和实现的接口。直到现在讲到了模板方法模式,再去看ArrayList的时候能明白不少。在前面的博客中有提到List接口和Cloneable接口是用来实现什么设计模式的。今天就来看看这个ArrayList的父类AbstractList。

  AbstractList就是我们前面适用场景中介绍的父类(也叫模板类),这个类里面即提供了公共的方法(不可供子类修改),又提供了可让子类修改的方法。下面我们直接看源码,由于方法很多,我们就介绍一下addAll方法。

public abstract class AbstractList
extends AbstractCollection
implements List
{ public boolean addAll(int index, Collection
c) { rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); modified = true; } return modified; }}

  上面的是AbstractList的addAll方法,可以看见这个方法没有限定子类是否去修改,子类由需要就去修改,如果子类不想修改,完全能够按照AbstractList中的逻辑添加元素。事实上我看了一遍AbstractList中的方法发现除了一些私有的方法不能给子类给子类访问之外,其余的基本上都是可以给子类去选择是否修改的。如果子类觉得父类的方法可行,那么直接使用父类的方法即可。

public class ArrayList
extends AbstractList
implements List
, RandomAccess, Cloneable, java.io.Serializable{ public boolean addAll(int index, Collection
c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }}

  上面这个就是ArrayList中的addAll方法。

  但是AbstractList里面有一个方法,就是get()方法,AbstractList明确要求要让子类实现。由于代码较少,我就直接截图

 

   左边是父类AbstractList中的,右边是ArrayList中的方法。在父类中没有直接写出实现代码,而是让子类自己手动去实现。除此之外其实还有一个方法就是AbstractList父类AbstractCollection中的toString方法。在ArrayList中是没有的,但是平常在写代码时候,是可以直接调用的,这就是一个公共的方法。

四、总结

  模板方法模式只需要简单的继承关系就可以完成。相信平常我们在写代码的时候也是使用过模板方法模式,只是我们并不知道是这种设计模式。这里多说一下,如果我们希望子类不要修改父类的方法,只需要加上final修饰即可;如果希望子类一定重写父类的方法,就将父类的方法用abstract修饰;如果子类可以修改也可以不修改,就可以像addAll方法那样设计即可。重点理解模板,这个模板尽量使用抽象类。因为抽象类比接口更加的灵活,能将模板定义的更好。其实看完上面的源码解析,总结起来就是一句话AbstractList是ArrayList的模板。

 

转载于:https://www.cnblogs.com/Cubemen/p/10682708.html

你可能感兴趣的文章
[问题2014S07] 解答
查看>>
hive-jdbc/odbc的解读和看法
查看>>
[LeetCode] Triangle
查看>>
poj2586 Y2K Accounting Bug(贪心)
查看>>
NSIS 资料
查看>>
Linux-进程基础
查看>>
Java 对文件的操作
查看>>
smarty模板引擎(一)基础知识
查看>>
让网站和APP更具动感的几点建议
查看>>
contentprovider的学习实例总结
查看>>
Ubuntu下在Apache中运行Keystone
查看>>
快捷键
查看>>
Java初学(二)
查看>>
opencv2对于读书笔记——二值化——thresholded功能
查看>>
krpano漫游加方向性3D声音(这篇文章已被移到krpano中国网站 krpano360.com)
查看>>
ZH奶酪:Python中zip函数的使用方法
查看>>
201507之佛山移动实习
查看>>
poj_1442 Treap
查看>>
renameTo()方法的用法
查看>>
Java25
查看>>