面试题:设计模式之六大设计原则

又是只能回答概念不能提出具体的实例出来论证所讲的观点(具体实例后面再补充吧)

单一职责原则

单一职责原则是指一个类只负责一个职责,它使得类的职责更单一。这样每个类只需要负责自己的那部分,类的复杂度就会下降。如果职责划分的很清楚,那么代码的维护难度降低。如果将所有功能都放在一个类中,那么这个类就会变得臃肿,一旦出现bug,要在所有代码中寻找问题所在;更改一处代码可能会改变整个代码的结构

  • 该原则不仅适用于类,对于接口和方法同样使用,即一个接口或方法,只负责一件事,这样的话,接口设计会变得简单,方法中的代码也会更少,易维护。而事实上,由于一些其他因素的影响,类的单一职责在项目中是很难保证的。通常接口和方法的单一职责更易实现

单一职责原则的优势

  • 类的复杂度降低
  • 类、接口、方法的职责明确,提高可读性
  • 可维护性高

开闭原则

在软件的生命周期内,因为变化,升级和维护等原因需要对软件原有代码进行修改,可能会给旧代码引入错误,也有可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现,即一个软件实体,如类、模块、函数应该对扩展开放,对修改关闭--开闭原则

  • 用抽象构建架构,用实现扩展细节。因为抽象的灵活性好,适应性广,只要抽象的合理,可以基本保证架构的稳定。而软件中易变的细节,我们用从抽象类的实现类来进行扩展,当软件需要发生变化时,我们只需要根据需求重新派生一个实现类来扩展即可,当然前提是抽象要合理,要对需求的变更有前瞻性和预见性

里式替换原则

里式替换原则是指所有引用基类的地方必须能透明地使用其子类的对象。意思是基类所在的地方,都可以替换成子类,程序还可以正常运行。这个原则跟面向对象的继承性密切相关

  • 做系统设计时,经常会设计接口或抽象类,然后由子类来实现抽象方法,这里使用的其实就是里氏替换原则

该原则的约束

  1. 子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法
    • 可以给父类的非抽象(已实现)方法加 final 修饰,这样就在语法层面控制了父类非抽象方法被子类重写而违反里氏替换原则
    • 有时候父类有多个子类(Son1、Son2),但在这些子类中有一个特例(Son2)。要想满足里氏替换原则,又想满足这个子类的功能时,有的伙伴可能会修改父类(Father)的方法。但是,修改了父类的方法又会对其他的子类造成影响,产生更多的错误。这是怎么办呢?我们可以为这个特例(Son2)创建一个新的父类(Father2),这个新的父类拥有原父类的部分功能(Father2并不继承Father,而是持有Father的一个引用,组合Father,调用Father里的功能),又有不同的功能。这样既满足了里氏替换原则,又满足了这个特例的需求
  2. 子类中可以增加自己特有的方法

  3. 当子类覆盖或实现父类的抽象方法时,方法的的形参要比父类方法的形参更宽松

  4. 当子类覆盖或实现父类的抽象方法时,方法的返回值要比父类更严格

迪米特原则

迪米特原则是指如果个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性

实现方式

  • 从依赖者的角度来说,只依赖应该依赖的对象
  • 从被依赖者的角度说,只暴露应该暴露的方法

迪米特原则的优势

  • 降低了类之间的耦合度,提高了模块的相对独立性
  • 由于耦合度降低,从而提高了类的可复用率和系统的扩展性

迪米特原则的缺点

  • 过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰

接口隔离原则

接口隔离原则是指要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用(该原则中的接口,是一个泛泛而言的接口,不仅仅指Java中的接口,还包括其中的抽象类)

  • 客户端不应该依赖它不需要的接口
  • 类间的依赖关系应该建立在最小的接口上

实现方式

  1. 根据接口隔离原则拆分接口时,首先必须满足单一职责原则

  2. 接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑

  3. 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法

  4. 了解环境,拒绝盲从。每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同,深入了解业务逻辑

  5. 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情

接口隔离原则的优势

  1. 将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性

  2. 接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性

  3. 如果接口的粒度大小定义合理,能够保证系统的稳定性;但是,如果定义过小,则会造成接口数量过多,使设计复杂化;如果定义太大,灵活性降低,无法提供定制服务,给整体项目带来无法预料的风险

  4. 使用多个专门的接口还能够体现对象的层次,因为可以通过接口的继承,实现对总接口的定义

  5. 能减少项目工程中的代码冗余。过大的大接口里面通常放置许多不用的方法,当实现这个接口的时候,被迫设计冗余的代码


依赖倒置原则

依赖倒置原则是指上层模块不应该依赖底层模块,它们都应该依赖于抽象,抽象不应该依赖于细节,细节应该依赖于抽象

posted @ 2022-07-04 22:25  伊文小哥  阅读(108)  评论(0编辑  收藏  举报