当前位置:   article > 正文

面向对象的设计原则(七大原则)_面向对象设计原则

面向对象设计原则

目录

七大原则

1、单一职责原则

2、开闭原则

3、里氏代换原则

4、依赖倒置原则

5、接口隔离原则

6、合成复用原则

7、迪米特法则


七大原则

对于面向对象的软件系统,在支持可维护性的同时,提高系统的复用性是一个很重要的问题。在面向对象的设计当中,可维护性是以设计原则为基础的。面向对象的原则包括七种。

1、单一职责原则

单一职责原则(SRP)Single Responsibility Principle

一个类只负责一个功能另有中的相应职责----------就一个类而言,应该只有一个引起它变化的原因;

也就是说一个类里最好是放一种类型的方法;比如:

DAO:只放操作数据库的方法;

Util:只放某个工具的方法;

……………………

单一职责原则:实现高内聚,低耦合;

2、开闭原则

开闭原则(OCP)------Open-Closed Principle:消灭分支语句 if...else...

软件的实体应该对拓展开放,对内修改关闭。

即:当有新的需求的时候,我们不用修改现在的代码,只需要添加新的代码就可以;

关键:抽象化,并从抽象化导出具体实现;

3、里氏代换原则

里氏代换原则(LSP)--------Liskov Substitution Prinicple

所有引用其父类的地方都能够透明的引用其子类;

不应该在代码中出现if/else之类对派生类类型进行判断的条件;

○ 派生类应当可以替换基类,并出现在基类能够出现的任何地方,或者说如果我们把代码中使用基类的地方用它的派生类所代替,代码还能正常工作;

里氏替换原则是使代码符合开闭原则的一个重要保证;

● 具体来说:子类可以扩展父类的功能,但不能改变父类原有的功能

○ 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法;

○ 子类可以增加自己特有的方法;

○ 当子类单独的方法重载父类的方法时,方法的前置条件(即方法的输入/入参)要比父类方法的输入参数更宽松;

○ 当子类的方法实现父类的方法时(重载/重写或实现抽象方法)的后置条件(即方法的输出/返回值)要比父类更严格或者相等;

里氏替换原则的优点:

● 约束继承泛滥,是开闭原则的一种体现;

● 加强程序的健壮性,同时变更时也可以做到非常好的提高程序的维护性、扩展性。降低需求变更时引入的风险;

重构违反LSP的设计:

如果两个具体的类A,B之间的关系违反了LSP,(假如是从B到A的继承关系),那么根据具体的情况可以在下面的两种重构方案中选择一种:

● 创建一个新的抽象类C,作为两个具体类的基类,将A,B的共同行为移动到C中来解决问题。

● 从B到A的继承关系改为关联关系;

4、依赖倒置原则

依赖倒置原则(DIP)------Dependece Inversion Principle

抽象不应该不依赖于细节,细节应该依赖于抽象;

即:针对接口编程,而不是针对实现编程。

A. 高层模块不应该依赖于低层模块,二者都应该依赖于抽象

B. 抽象不应该依赖于细节,细节应该依赖于抽象

C.针对接口编程,不要针对实现编程。

依赖:在程序设计中,如果一个模块a使用或者调用了另一个模块b,那么就是模块a依赖模块b;

高层模块与底层模块:在一个应用程序中,我们有一些低层次的类,这些类实现了一些基本的或者初级的操作,我们称之为低层模块;另外有一些高层次的类,这些类封装了某些复杂的逻辑,并且依赖于低层次的类,这些类我们称之为高层模块;

依赖倒置:面向对对象程序设计相对于面向过程(结构化)程序设计而言,依赖关系被倒置了。因为传统的结构化程序设计中,高层模块总是依赖于低层模块。

一个良好的设计应该是系统的每一部分都是可替换的。如果高层模块过分依赖低层模块,一方面一旦底层模块需要替换或者修改,高层模块将受到影响;另一方面,高层模块很难可以重用;

解决方案:在高层模块和低层模块之间,引入一个抽象接口层。

高层---->抽象接口层---->低层

High level Policy -------->Abstract Interface--------->Detailed Implementation

抽象接口是对低层模块的抽象,低层模块继承或者实现该抽象接口;

这样,高层模块不直接依赖低层模块,而是依赖抽象接口层。抽象接口也不依赖低层模块的实现细节,而是低层模块依赖(继承或者实现)抽象接口;

类和类之间都通过抽象接口层来建立关系。

怎么使用依赖倒置原则:

1、依赖于抽象

● 任何变量都不应该持有一个指向具体类的指针或引用。

● 任何类都不应该从具体类派生

2、设计接口而非设计实现

● 使用继承避免对类的直接绑定

● 抽象类/接口:倾向于较少的变化;抽象是关键点,它易于修改和扩展;不要强制修改那些抽象类或者接口;

3、避免依赖的传递

● 避免高层依赖于低层

● 使用继承和抽象类来有效的消除传递依赖

依赖倒置原则的优点:

可以减少类间的耦合性、提高系统的稳定性,提高代码可读性和可维护性,可降低修改程序所造成的的风险。

5、接口隔离原则

接口隔离原则(ISP)Interface Segregation Principle

不能强迫用户去依赖那些他们不使用的接口。即:使用多个专门的接口会比使用单一的总接口好;

● 接口的设计原则:接口的设计应该遵循最小接口原则,不要把用户不使用的方法也塞到同一个接口里面;如果一个接口的方法没有被使用到,这说明应该将其分割成几个功能转移的接口;

● 如果一个接口a继承另一个接口b,则接口a相当于继承了接口b的方法,那么继承了接口b之后,接口a也应该遵循上述原则:不应该包含用户不使用的方法。繁殖,则说明接口a被接口b污染了,应该重新设计关系;

接口分隔原则:

1、一个类对一个类的依赖应该建立在最小的接口上

2、建立单一接口,不要建立庞大臃肿的接口

3、尽量细化接口,接口中的方法尽量少

6、合成复用原则

合成复用原则(CARP)----Composite/Aggregate Reuse Principle

尽量使用对象组合,而不是继承来达到复用的目的;

相对于继承复用而言,其耦合性相对较低,成员对象对新对象影响不大。可动态运行。复用时尽量减少组合/聚合关系,少用继承;

合成复用原则优缺点:

优点:

● 新对象存取子对象的唯一方法是通过子对象的接口。

● 这种复用是黑箱复用,因为子对象的内部细节是新对象所看不见的。

● 这种复用更好地支持封装性。

● 这种复用实现上的相互依赖性比较小。

● 每一个新的类可以将焦点集中在一个任务上。

● 这种复用可以在运行时间内动态进行,新对象可以动态的引用与子对象类型相同的对象。

● 作为复用手段可以应用到几乎任何环境中去。

缺点:

系统中会有较多的对象需要管理。

通过继承来实现复用的优缺点:

优点:

● 新的实现较为容易,因为基类等等大部分功能可以通过继承的关系自动进入派生类;

● 修改和扩展继承而来的实现较为容易;

缺点:

● 继承复用破坏封装性,继承将基类的实现细节暴露给派生类。由于基类的内部细节常常是对于派生类透明的,所有这种复用是透明的复用,又称“白箱”复用;

● 如果基类发生改变,那么派生类的实现不得不发生改变;

● 从基类继承而来的实现是静态的,不可能在运行时间内发生改变,没有足够的灵活性。

7、迪米特法则

迪米特法则(LoD)------Law of Demeter

又叫做最少知道原则(Least Knowledge Principle)

一个软件实体应当尽可能少的与其他实体发生相互作用;

每一个软件单位对其他的单位都只有最少的只是,而且局限于那些本单位密切相关的软件的单位;

例如:

购房者要购买楼盘A、B、C中的楼,他不必直接到楼盘去买楼,而是可以通过一个售楼处去

了解情况,这样就减少了购房者与楼盘之间的耦合。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/404018
推荐阅读
相关标签
  

闽ICP备14008679号