一、引子
从学编程一开始就被告知,要想做一名优秀的程序员两大必要技能:1.源码阅读(JDK、C等底层语言封装) 2.设计模式(使用某种语言优雅的落地典型场景功能)。一般随着工作年限的增长,被迫对底层语言/框架源码阅读的越来愈多,但是设计模式如不刻意去学习,永远不会真正掌握。笔者把设计模式比喻成程序员的“绝世神功”,掌握了设计模式,对快速阅读源码、优雅地编写程序有极大的促进作用,可以说就像打通了任督二脉一样。
1.1 设计模式由来
1995年,GoF(Gang of Four四人帮)合作出版了《设计模式:可复用面向对象软件的基础》(Design Patterns – Elements of Reusable Object-Oriented Software) 一书,书中总结了23种面向对象设计模式,也就是大名鼎鼎的GOF设计模式。
1.2 23种 VS 24种
一直听说有24种设计模式(网上一大堆标题24种设计模式,然后列举的只有23种,也是无语),公认的GOF只有23种,还有一种是啥?大部分文章都说是简单工厂模式(Simple Factory)。笔者搜遍全网(连chatGPT也问了),没找到第24种设计模式谁提出的。这第24种设计模式,有说是简单工厂模式,也有说是静态工厂模式,也有说简单工厂模式=静态工厂模式,真是一塌糊涂,乱七八糟。神奇的是这些文章的作者都没深究过这个问题,估计大都是拿来主义。
到底几种?
---23种!!!即GOF的23种设计模式即可。还有2个模式:简单工厂、静态工厂,确实在后续应用比较多,但在1995年未列入GOF。
二、知识预备
想要练成绝世武功,内功心法和外家套路缺一不可。要想练成“设计模式”这一绝世武功,“面向对象设计原则”就是内功心法(遵循的设计原则),“UML统一建模语言”就是外家套路(代码落地建模工具)。练功之前,咱们先简单学习下这2个必备的基础技能。
2.1 面向对象设计原则
面向对象设计的目标之一就是支持可维护性复用,一方面需要实现设计方案的重用,另一方面要确保系统易于拓展和修改,具有较好的灵活性。7种面向对象设计原则,其中前5条是强约束性的建议都做到,后2条尽量做到即可。
1、单一职责原则(Single Responsibility Principle , SRP):一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。--单一职责原则是实现高内聚低耦合的指导方针。
理解:
- 一个类只负责一个职责。
2、开闭原则(Open Close Principle):对扩展开放,对修改关闭。--开闭原则是面向对象设计的目标。
理解:
- 使用接口和抽象类。实现不修改原代码,又可以拓展新方法。
3、里氏代换原则(Liskov Substitution Principle):所有引用基类(父类)的地方必须能透明地使用其子类的对象。--里氏代换原则是实现开闭原则的基础。
理解:
- 把父类设计为抽象类或者接口。
- 子类必须实现父类的所有方法。
4、依赖倒转原则(Dependence Inversion Principle):高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不依赖于细节,细节应该依赖于抽象。--依赖倒转原则就是面向对象设计的主要手段。
理解:
- 要针对接口编程,不要针对实现编程。
- 依赖注入:将一个类的对象传入另一个类,注入时尽量注入父类对象,程序运行时通过子类对象覆盖父类对象。
5、接口隔离原则(Interface Segregation Principle):客户端不应该依赖那些它不需要的接口(方法),--接口级的单一职责原则。
理解:
- 大接口要分割成小接口,接口专用。
- 客户端使用专用接口。
6、迪米特法则(Demeter Principle):即最少知道原则,一个实体应当尽量少的与其他实体之间发生相互作用,减少耦合。
理解:
- 依赖者只依赖该依赖的对象,被依赖者只暴露该暴露的对象。
7、合成复用原则(Composite Reuse Principle):尽量使用合成/聚合的方式,而不是使用继承,降低耦合。
理解:
- 少用继承,降低耦合。
2.2 UML建模
UML1.X有9个图,UML2.0有12个图,具体如下图所示:
一般,我们掌握 UML1.X 常用的9种图即可,分为两类:
- 静态图:用例图、类图、包图、对象图、部署图
- 动态图:顺序图(时序图),通信图(UML1.x 时称为协作图),状态机图,活动图