内容简介:相信很多人都听过一个问题:把大象关进冰箱门,需要几步?第一,把冰箱门打开;第二,把大象放进去;第三,把冰箱门关上。我们可以看见,这个问题的答案回答的很有步骤。接下来我们介绍一种设计模式——模板方法模式,你会发现,它与这个问题的答案实际上有很多共同之处。定义一个算法骨架,允许子类为一个或多个步骤提供实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
前言:
相信很多人都听过一个问题:把大象关进冰箱门,需要几步?
第一,把冰箱门打开;第二,把大象放进去;第三,把冰箱门关上。我们可以看见,这个问题的答案回答的很有步骤。接下来我们介绍一种设计模式——模板方法模式,你会发现,它与这个问题的答案实际上有很多共同之处。
一、定义
定义一个算法骨架,允许子类为一个或多个步骤提供实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
二、适用场景
一次性实现一个算法的不变的部分,将可变的行为留给子类实现
也就是将各子类中公共行为被提取出来并集中到一个公共父类中,从而避免代码重复。还是拿上面大象放进冰箱里面的例子,打开冰箱和关上冰箱都是不变的行为,我们可以将其放在公共父类实现。但是放大象,怎么放?是先放背对着冰箱放,还是面对着冰箱放。不想放大象,放老虎或者其他动物呢?这些就是我们可变的行为,这个就放入子类中实现。可以说,模板方法提供了一个很好的代码复用平台
三、JDK中的模板方法模式
在刚接触ArrayList的时候一直没注意它继承的类和实现的接口。直到现在讲到了模板方法模式,再去看ArrayList的时候能明白不少。在前面的博客中有提到List接口和Cloneable接口是用来实现什么 设计模式 的。今天就来看看这个ArrayList的父类AbstractList。
AbstractList就是我们前面适用场景中介绍的父类(也叫模板类),这个类里面即提供了公共的方法(不可供子类修改),又提供了可让子类修改的方法。下面我们直接看源码,由于方法很多,我们就介绍一下addAll方法。
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { public Boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Boolean modified = false; for (E e : c) { add(index++, e); modified = true; } return modified; } }
上面的是AbstractList的addAll方法,可以看见这个方法没有限定子类是否去修改,子类由需要就去修改,如果子类不想修改,完全能够按照AbstractList中的逻辑添加元素。事实上我看了一遍AbstractList中的方法发现除了一些私有的方法不能给子类给子类访问之外,其余的基本上都是可以给子类去选择是否修改的。如果子类觉得父类的方法可行,那么直接使用父类的方法即可。
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { public boolean addAll(int index, Collection<? extends E> 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的模板。
读者福利:
分享免费学习资料
针对于 Java 程序员,我这边准备免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)
为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!
资料领取方式:加入Java技术交流群 963944895
, 点击加入群聊 ,私信管理员即可免费领取
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Mybatis源码解读-设计模式总结
- OKHTTP3源码和设计模式(下篇)
- 从shiro源码角度学习工厂方法设计模式
- 从shiro源码角度学习建造者设计模式
- 从源码角度理解Java设计模式——装饰者模式 原 荐
- 设计模式之发布订阅模式(5) Spring Events源码解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Design for Hackers
David Kadavy / Wiley / 2011-10-18 / USD 39.99
Discover the techniques behind beautiful design?by deconstructing designs to understand them The term ?hacker? has been redefined to consist of anyone who has an insatiable curiosity as to how thin......一起来看看 《Design for Hackers》 这本书的介绍吧!