首页 > 技术文章 > 面向对象设计六大原则

dawnlight 2021-11-09 23:29 原文

面向对象设计六大原则

1、单一职责原则(SRP)


定义:
一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。
单一职责原则是实现高内聚、低耦合的指导方针,是最简单却最难运用的原则,需要设计人员发现类的不同职责并将其分离。


单一职责原则的优点:

  • 类的复杂性降低,实现什么职责都有明确的定义;
  • 逻辑变得简单,类的可读性提高了,而且,因为逻辑 简单,代码的可维护性也提高了;
  • 变更的风险降低,因为只会在单一的类中的修改。

2、开闭原则(OCP)


定义:
一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
也就是说,一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码实现变化。这是为软件实体的未来事件而制定的对现行开发设计进行约束的一个原则。

在我们编码的过程中,需求变化是不断的发生的,当我们需要对代码进行修改时,我们应该尽量做到能不动原来的代码就不动,通过扩展的方式来满足需求。


3、里氏替换原则(LSP)


定义:
所有引用基类的地方必须能透明地使用其子类的对象。
通俗点说,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何异常。 但是反过来就不行了,因为子类可以扩展父类没有的功能,同时子类还不能改变父类原有的功能。

我们都知道,面向对象的三大特征是封装、继承和多态,这三者缺一不可,但三者之间却并不 “和谐“。因为继承有很多缺点,当子类继承父类时,虽然可以复用父类的代码,但是父类的属性和方法对子类都是透明的,子类可以随意修改父类的成员。如果需求变更,子类对父类的方法进行了一些复写的时候,其他的子类可能就需要随之改变,这在一定程度上就违反了封装的原则,解决的方案就是引入里氏替换原则。

里氏替换原则为良好的继承定义了一个规范,它包含了4层含义:

1、子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。

2、子类可以有自己的个性,可以有自己的属性和方法。

3、子类覆盖或重载父类的方法时输入参数可以被放大。


4、依赖倒转原则(DIP)


定义:
高层模块不应该依赖底层模块,它们都应该依赖抽象;
抽象不应该依赖于细节;
细节应该依赖于抽象。
依赖倒转原则要求:要针对接口编程,不要针对实现编程。


5、接口隔离原则(ISP)


定义:
客户端不应该依赖那些它不需要的接口。


建立单一接口,这不是单一职责原则吗?其实不是,单一职责原则要求的是类和接口职责单一,注重的是职责,一个职责的接口是可以有多个方法的,而接口隔离原则要求的是接口的方法尽量少,模块尽量单一,如果需要提供给客户端很多的模块,那么就要相应的定义多个接口,不要把所有的模块功能都定义在一个接口中,那样会显得很臃肿。


6、迪米特法则(LOD)


定义:
一个对象应该对其他对象有最少的了解。

也就是说,一个类应该对自己需要耦合或调用的类知道的最少,类与类之间的关系越密切,耦合度越大,那么类的变化对其耦合的类的影响也会越大,这也是我们面向设计的核心原则:低耦合,高内聚。

迪米特法则还有一个解释:只与直接的朋友通信。

我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。

推荐阅读