近期在专心学习设计模式,打好自己的技术底子。《深入浅出设计模式》这本书是入门设计模式的好选择。这篇博客是我对书中第一章要点的总结,将重要的信息整理出来,方便复习巩固。
由于本人还是个 Java 小白,难免会有些错漏之处,还请大家不吝指出。如果我写的文章对大家有所帮助,还请多多点赞支持,谢谢!
为什么要学习设计模式?
设计模式是前人软件开发过程中总结下来的优秀经验,可以提高我们软件开发的效率,并且能够帮助我们开发出更好的软件。
要想更进一步地提升自己的技术水平,就离不开框架源码的阅读,而框架源码中一般都会使用到很多的设计模式。因此,学习设计模式可以帮助我们更好地理解框架源码。
如果你想要设计出好的应用程序,那么你必须好好学习设计模式。
切入正题
A —— Java 开发大师级别人物;B —— Java开发小白
A:现在要开发一款鸭子模拟器,这款模拟器程序中有很多的鸭子类型,每种鸭子类型又有其属性和行为,我们如何设计好这款应用?(何谓设计好?)
B:可以定义 Duck 父类,Duck 下有很多不同类型的鸭子子类。
A:若如果现在需要增加鸭子模拟器的功能,让鸭子实现“飞”这个动作,该怎么做?
B:在 Duck 类中新定义(并实现)一个 fly()
方法。
A:这会导致一个问题,“橡皮鸭”也继承自 Duck 类型,但“橡皮鸭”是不会飞的。从这里我们可以看到继承的一个缺点——继承可能会导致“溢出效应”。即我只是对父类进行了局部修改,却影响到了所有子类。
B:我们可以将 fly()
方法在“橡皮鸭”这个类中重写。
A:假如因为业务需要,每个月都要引入若干鸭子类型呢,比如“诱饵鸭”?这种鸭子不会飞,也不会叫,那就得重写相应的方法。每次都需要重写代码,这不是种好的改进思路。
B:将 fly()
和 quack()
方法放到接口中,让需要实现这些方法的类实现对应的接口
A:这样会导致大量重复代码,每个类都要编写实现代码,十分繁琐,而且当需要改动实现的代码时,每个实现了这个接口的类都要进行相应的改动,这是件很麻烦的事情。
A:对于这个问题,我们可以采用策略模式解决。将应用中会变化的部分封装起来,使其与不需要变化的部分隔离开。在这个例子中,不同鸭子类型的“叫”和“飞”这两个行为可能不同,因此可以考虑将这些行为封装起来。
B:策略模式?具体该如何封装变化的部分呢?
A:我们可以将“飞”和“叫”这两个行为也当作类来看待。“飞”这个类又有很多的子类:“用翅膀飞”、“用螺旋桨飞”、“不会飞”等等,“叫”这个行为也是类似的思路。
A:定义的类图如下:
A:
A:JDK 源码中 Arrays 的 Comparator 使用到了策略模式,有兴趣可以读一读它的源码体会一下。