面向对象编程设计原则

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象编程设计原则相关的知识,希望对你有一定的参考价值。

  1. 1.       单一职责 (SOP Single Responsibility Principle
  2. 2.       里氏替换(LSP Liskov Substitution Principle
    1. 子类必须完全实现父类的方法

注:若子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖,聚集,组合等关系代替继承

  1. 子类可以有自己的个性
  2. 覆盖或实现父类的方法时输入参数可以被放大

方法中的输入参数为前置条件(即,契约原则,先定义出WSDL接口,制定好双方的开发协议,然后再各自实现);

    里氏替换原则也要求制定一个契约,就是父类或接口。契约制定好了,也就同时制定了前置条件和后置条件,前置条件是你要我执行,就必须满足我的条件;后置条件就是我执行完了需要反馈,标准是什么;

如:与父类的方法名相同,参数不同的话,即为重载(Overload)而非覆写(Override)

    若,父类方法输入的是HashMap类型,子类输入的参数是Map类型,也就是说子类输入参数类型的范围扩大了,子类替代父类传递到调用者中,子类的方法永远都不会被执行。但是,如果Father类输入的参数类型宽于子类的输入参数类型,则父类存在的地方子类未必可以存在,因为一旦把子类作为参数传入,调用者就很可能进入子类方法的范畴。

  1. 覆写或实现父类的方法时输出结果可以被缩小

即,父类一个方法的返回值是T,子类相同的方法(覆写或重载)的返回值为S,则里氏替换原则要求S<=T。

  1. 3.       依赖倒置(DIP Dependence Inversion Principle

3.1

a.高层模块不应该依赖底层模块,两者都应该依赖其抽象

b.抽象不应该依赖细节

c.细节应该依赖抽象

3.2对象的依赖关系的三种传递方式

  a. 构造函传递依赖对象

  b. Setter方法传递依赖对象

  c. 接口声明依赖对象(接口注入)

注:a. 每个类尽量都有接口或抽象类,或抽象类和接口两者都具备

    b. 变量的表面类型尽量是接口或抽象类

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

    d. 尽量不要覆写基类的方法

    e.结合里氏替换原则使用

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

4.1接口分类

    a. 实例接口(Object Interface), 即声明一个类,通过new关键字产生

    b. 类接口(Class Interface) interface关键字定义的接口

4.2 接口设计原则

    a. 接口要尽量小(拆分接口时,首先必须满足单一职责原则)

    b. 接口要高内聚(提高接口、类、模块的处理能力,减少对外的交互)

        注:在接口中尽量减少公布public方法,接口是对外的承诺,承诺越少越利于系统开发,变更的风险也越少,同时降低成本。

4.3 定制服务(只提供访问者需要的方法)

4.4 接口设计是有限度的

总结:接口隔离原则是对接口的定义,同时也是对类的定义,接口和类尽量使用原子接口或原子类来组装。

  1. 一个接口只服务于一个子模块或业务逻辑
  2. 通过业务逻辑压缩接口中public方法
  3. 已经被污染的接口,采用适配器模式进行转化
  4. 结合实际,具体应用

 

  1. 5.       迪米特法则(LOD Law of Demeter)即最少知识原则(LKP Least Knowledge Principle

一个对象应该对其他对象有最少的了解,其核心观念:类间解耦,若耦合

  1. 6.       开闭原则(OCP Open Closed Principle)

定义:软件实体应对扩展开放,对修改关闭,即一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。软件包括:项目或软件产品中按照一定的逻辑规则划分的模块;抽象和类;方法

尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来完成变化

扩展:将价格定义为int并非错误, 在非金融类项目中对货币处理时,一般取两位精度,通常的设计方法是在运算过程中扩大100倍,在需要展示时在缩小倍,减少精度带来的误差。

增加一个子类,覆写发生变化的方法,高层次的模块(即需要变化的模块static)通过新这类产生新的对象,完成业务变化对系统的最小开发。

 

变化可归纳为:

  1. 逻辑变化
  2. 子模块变化(会对其他模块产生影响,尤其低层次的模块必然引起高层次模块变化)
  3. 可见视图变化

 

6.1开闭原则对测试的影响

         新增加一个子类,要新增加一个对应的测试类

6.1.2开闭原则可以提高复用性

6.1.3开闭原则可提高可为维护性

6.1.4面向对象开发的要求

6.2 开闭原则的具体应用

a. 抽象约束

通过接口或抽象类可以约束一组可能变化的行为,并且能够实现对扩展开放,其包含三层含义:第一,通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;

第二,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;

第三,抽象层尽量保持稳定,一旦确定即不允许修改

b. 元数据(metadata)控制模块行为

  元数据:描述环境和数据的数据,即配置参数,可以从文件中获得,也可以从数据库中获得。

  1. 制定项目章程
  2. 封装变化:第一,将相同的变化封装到一个接口或抽象类中;

第二,将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中

以上是关于面向对象编程设计原则的主要内容,如果未能解决你的问题,请参考以下文章

面向对象编程中的6大设计原则

面向对象编程设计原则

面向对象编程设计原则

面向对象编程的七大设计原则

Java 设计模式 Day3 之面向抽象原则:什么是面向抽象编程?面向抽象编程如何应用?

Java 设计模式 Day3 之面向抽象原则:什么是面向抽象编程?面向抽象编程如何应用?