设计模式的7大原则
下面是我对设计的7个原则的个人理解,如有不妥之处,欢迎大家指出:
23种设计模式,其实都是在下面7大原则的基础上,设计出来适合目前大部分实际开发中所遇到的问题的方案
单一原则
- 每个类只应该拥有一个一个职能,也就是说,当需求改变时,修改一个类只会因为一个原因
- 如果一个类有多个职能,当其中一个职能被修改时,很可能会影响这个类的其他职责
- 这样的设计是脆弱的,极容易发生问题,如果如果发现一个类有个职责,我们应该考虑去拆分它了
里氏替换原则
- 一个软件实体(类、模块、函数等等),子类可以替换父类,如果我们将子类替换掉父类,程序的行为不应该发生变化,那么这个就符合里氏替换原则
- 只有当子类可以替换父类时,类才真正被复用了
开放封闭原则
- 软件实体应该对修改封闭,对扩展开放
- 因为修改之前的代码容易发生不可预测的问题
- 但是需求不可能永远不变,设计人员必须猜测最有可能发生的变化的种类,然后构造抽象来隔离那些变化
- 假定不会发生变化的类,如果发生类变化,我们就创建抽象来隔离以后发生变化的同类变化。(比如简单工厂模式中的 计算器)
- 里氏替换原则是开发封闭原则的基础
迪米特法则
- 如果2个类不会相互作用,我们就应该让2个类不产生直接的联系
- 如果一个类需要调用另外一个类,我们可以通过第三方去调用,这样2个类就可以尽可能的降低耦合度
- 策略模式中的Client和策略就通过Context进行调用,从而减少了Client和策略之间的耦合度
依赖倒转
依赖倒转其实可以说是面向对象设计的标志,而哪种语言来编写不重要,如果编写时考虑的都是针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止与抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了
- Spring的设计思想之一就是“依赖倒转”
- 高层模块不应该依赖于低层模块。两个都应该依赖抽象。
- 在程序设计时,我们应该面向接口编程,而不是细节,只有面向接口编程的设计,才是真正的面向对象的设计,否则就是面向过程的设计
合成、聚合原则
- 程序中,如果都使用继承的方式扩展类,那么类将会变得非常大,而难以维护
- 所以,我们应该尽量使用合成、聚合的方式去替代类的继承
- 合成、聚合的方式也提高的类的利用率
- 聚合表示一种弱的‘拥有’关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;
- 合成则是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样
接口隔离原则
- 一个接口应该只有一个职责
- 如果一个接口有过多的职责,我们应该想办法将它拆分成多个接口
其他相关概念
高内聚和低耦合
- 内聚:描述的是一个对象内部组成部分之间相互联系的紧密程度。
- 耦合:描述的是一个对象和其他对象之间联系的紧密程度。
所以,我们希望一个对象内部是紧密内聚的,而对象和对象之间是松耦合的。