一、类与类的关系
泛化
- 用 空心三角箭头的实线 表示
- 子类(子接口)继承父类(父接口)的关系
实现
- 用 空心三角箭头的虚线 表示
- 实现类 实现接口 的关系
依赖
- 普通箭头、虚线 表示
- 类A使用类B的关系,关系比较微弱,具有偶然性、临时性
常用类B作为类A的某个方法入参,只有调用该方法时才有联系。
关联
- 用 普通箭头的实线 表示
- 类A为类B成员变量,强依赖、非临时性、长期性
A可为B的成员变量,B也可以为A的成员关联,如果互为成员变量,则为双向关联。也有自关联(箭头指向自己)
聚合
- 用 普通箭头 + 空心菱形箭尾 的实线 表示
- 类A包含类B,与关联相似,整体和部分的关系
- has-a
区分于关联关系,A包含B,但A和B不平等,整体和部分的关系。实际情况要根据语义来看。
组合
- 用 普通箭头 + 实心菱形箭尾 的虚线 表示
- 类A包含类B,强聚合
- contains-a
区分于聚合关系,组合为强聚合关系。在聚合关系中,A和B脱离之后仍与意义。组合关系不能脱离。实际情况要根据语义来看。
二、设计模式的七大原则
1)开闭原则(核心原则)
Open Close Principle
定义:一个软件实体应该对扩展开放,修改关闭
2)单一职责原则
Single Responsibility Principle
定义:对于一个类而言,应当仅有一个引起它变化的原因。
通俗来说,一个类承担的职责应尽量集中。如果一个类包含很多其他的功能,当某一功能发生变化时,会引起维护的困难性。
软件开发周期中,在需要新增功能时,不应当修改原有的代码实现变化,而是通过扩展基类的方式,进行变化。
核心语句是:用抽象构建框架,用实现扩展细节。
3)里式替换原则
Liskov Substitution Principle
定义:所有引用父类的地方必须能透明的使用其子类的对象
即使用父类的地方,替换成子类依旧可以使用;使用子类的地方,不能替换成父类。即子类不要重写父类已经实现的方法,通过增加新方法来实现新的功能。
- 子类可实现父类抽象方法,但不要重写父类已实现的方法(非抽象方法);
- 子类通过增加新方法来增加新功能(子类独有的方法);
- 子类重载或实现父类方法时,输入参数可以更宽松;
- 子类重载或实现父类方法时,返回值可以更严格;
4)依赖倒转原则
Dependence Inversion Principle
定义:
- 高层模块不应该依赖底层模块,二者应当依赖抽象;
- 抽象不应依赖于细节
- 细节应当依赖抽象
即面向接口(抽象类)编程。
使用任意类时应当以抽象类来实例化,即精良每个类都有着一个抽象的接口。在使用某类作为参数入参时,也尽量使用该类的抽象接口,而不是该类本身。
5)接口隔离原则
Interface Segregation Principle
定义:使用多个隔离的接口,而不是一个接口包含很多功能
即:接口的单一职责化。
子类实现多个隔离的接口比实现一个具有很多功能的接口更好。
6)迪米特(最少知道)原则
Demeter Principle
定义:一个类应当对其他对象有最少的了解
即:不关注耦合类的集体实现,而是只调用耦合类提供的公共方法。
比如 A 类耦合 B 类。在 A 类内部只需调用 B 类提供的公共方法,而不是调用 B 类方法后又返回一个新的 C 类,然后又对 C 类进行处理。 A类不应当关心B类的具体实现和耦合关系。
7)合成复用原则
Composite Reuse Principle
定义:尽量使用对象组合的方式,而非使用继承。
三、23种设计模式分类
1)创建型模式(5种)
工厂方法模式、抽象工厂、单例模式 、建造者模式、原型模式