七大设计原则和UML类关系

139 阅读3分钟

目的

解决软件的耦合性、内聚性、可扩展性、重用性、灵活性

  • 重用性:相同功能的代码,不用多次编写
  • 可读性:便于其他人阅读
  • 可扩展性(可维护性):方便添加新功能
  • 可靠性:增加新功能,对原功能没影响

单一职责原则

  • 降低类的复杂度,一个类只负责一项职责
  • 提高类的可读性,可维护性
  • 降低变更引起的风险
  • 特殊情况下,比如类中方法数量少,可以在方法级别保持单一职责原则

接口隔离原则

  • 客户端不要实现不需要的接口,即一个类对另一个类的依赖应该建立再最小的接口上
  • 接口隔离原则的要点就是要细化接口,客户端只实现需要的接口和里面的方法。
  • 好处:避免接口污染、提高灵活性、提供定制服务、实现高内聚

依赖倒置原则

  • 底层模块尽量都有抽象类或接口,或两种都有,程序稳定性更好
  • 变量的声明类型尽量是抽象类或接口,这样对于变量引用(形参)和实际对象(实参)来讲,就利于扩展和优化
  • 继承时遵循里氏替换原则
  • 高层模块不应该依赖低层模块,它们都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象
  • 依赖倒置原则也可以理解为“依赖抽象原则”

里氏替换原则

继承的思考.png 若有两个条件:

  • A条件:将程序P中的类1的对象o1改为类2的对象o2,而程序P的行为没有发生变化
  • B条件:类1是父类,类2是子类

根据里氏替换原则的第一个定义,A条件可以推导出B条件;
根据里氏替换原则的第二个定义,B条件可以推导出A条件;
所以,里氏替换原则其实就是:A条件和B条件互为充要条件。

在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法,继承实际上让两个类耦合性增强了,如果必须重写,可以通过聚合,组合,依赖的方式,重新写一个基类让之前的父子类变成兄弟类来解决问题。

里氏替换原则的意义,就是规范继承的用法,让我们最大限度地发挥继承的优点。

开闭原则

对扩展开放(提供方),对修改关闭(使用方)

迪米特法则

迪米特介绍.png 6) 避免类中出现非直接朋友关系的耦合

合成复用原则

  • 尽量使用依赖、聚合、组合的方式,而不是使用继承
  • 能使用依赖、聚合、组合,就不要用继承

UML类关系

依赖

  1. 类中用到了对方
  2. 类的成员属性
  3. 方法的返回类型
  4. 方法的接收参数类型(重要)
  5. 方法体中使用的局部变量(重要)
  • A类用到了B类,就说A依赖B

泛化

  • 泛化=继承,是依赖的一种特例
  • A类继承了B类,就说A和B存在泛化关系

实现

A类实现了B类接口,就是实现关系,是依赖的一种特例

关联

  • 关联关系就是类与类之间的联系,是依赖的特例
  • 关联有导航性:即双向关系或单向关系
  • 关系有多重性: 关联关系.png

聚合

  • 聚合表示整体与部分的关系,整体与部分可以分开
  • 聚合是关联的特例,所以具有关联的导航性与多重性

组合

  • 若整体和部分是不可分离的,则为组合关系

例子:有三个实体:Person、IDCard、Head,那Head和Person是组合,IDCard和Person是聚合。 但是若在Person中对IDCard进行级联删除,即删除Person时连IDCard一起删除,那IDCard和Person是组合了。