关于设计原则的理解
# 关于设计原则的理解
# 七大设计原则口诀
- 开:面向扩展开,面向修改关闭
- 口:接口隔离原则
- 合:合成/聚合复用原则
- 里:里氏替换原则
- 最:迪米特法则,又叫最少知识原则
- 单:单一职责原则
- 依:依赖倒置原则
- 单一职责原则告诉我们实现类要职责单一。用于指导类的设计,增加一个类时使用单一职责原则来核对该类的设计是否纯粹干净。也就是让一个类的功能尽可能单一,不要想着一个类包揽所有功能。
- 里氏替换原则告诉我们不要破坏继承体系。用于指导类继承的设计,设计类之间的继承关系时,使用里氏替换原则来判断这种继承关系是否合理。只要父类能出现的地方子类就能出现(就可以用子类来替换它),反之则不一定。
- 依赖倒置原则告诉我们要面向接口编程。用于指导如何抽象,即要依赖抽象和接口编程,不要依赖具体的实现。
- 接口隔离原则告诉我们在设计接口的时候要精简单一。用于指导接口的设计,当发现一个接口过于臃肿时,就要对这个接口进行适当的拆分。
- 开放封闭原则告诉我们要对扩展开放,对修改封闭。开放封闭原则可以说是整个设计的最终目标和原则!开放封闭原则是总纲,其他原则是对这个原则的具体解释。
- 迪米特法则告诉我们每个类尽量减少对其他类的依赖,类之间耦合越弱,越有利于复用。一个处于弱耦合的类被修改, 不会对有关系的类造成波及。如果类之间真的有需要建立联系,也希望能通过它的友元类来转达,但可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系——这在一定程度上增加了系统的复杂度。
- 合成/聚合复用原则告诉我们尽量通过合成/聚合的方式提高类的复用性,而不是通继承的方式。合成/聚合有助于保持每个类的封装,让类和类的层次保持在小规模,并且每个类的增长是可控的。反观如果通过继承的方式来实现类的复用,子类的实现与父类的紧密的依赖关系反而会限制了灵活性并最终限制了复用性。例如父类的实现中任何变化必然会导致子类的变化,当复用子类时,继承下来的实现可能不适合新的问题,那么父类就需要重写或者被别的类替代。甚至如果滥用继承机制,必定会导致类之间的层级关系越来紧密,类与类必定会走向高耦合。
# 不一定要完全遵循设计原则
软件设计是一个循序渐进、逐步优化的过程,而设计原则是软件设计的核心思想和规范。那么在实际的项目开发中,是否一定要遵循这些设计原则?
答案不总是肯定的,要视情况而定。因为在实际的项目开发中,必须要按时按量地完成任务。项目的进度受时间成本、测试资源的影响,而且程序也一定要保证稳定可靠。例如在单一职责原则中提到的例子,面对需求的变更,我们有三种解决方法:
- 方法一:直接改原有的函数,这种方式最快速,但后期维护最困难,而且不便拓展,是一定要杜绝的。
- 方法二:增加一个新方法,不修改原有的方法,这在方法级别上是符合单一职责原则的,但会给上层的调用增加不少麻烦。在项目比较复杂,类比较庞大,而且测试资源比较紧缺时,增加新方法不失为一种快速和稳妥的方式。因为如果要进行大范围的代码重构,势必要对影响到的模块进行全覆盖的测试回归,才能确保系统的稳定可靠。
- 方法三:增加一个新的类来负责新的职责,两个职责分离,这是符合单一职责原则的。在项目首次开发或逻辑相对简单的情况下,需要采用这种方式。
在实际的项目开发中,我们要尽可能地遵循这些设计原则。但并不是要100%地遵从,需要结合实际的时间成本、测试资源、代码改动难度等情况进行综合评估,适当取舍,采用最高效合理的方式。
参考:
罗伟富. 《人人都懂设计模式:从生活中领悟设计模式:Python实现》. 电子工业出版社
上次更新: 5/21/2023, 11:34:33 PM