面向对象的设计原则

面向对象三大特性:封装,继承,多态。


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

一个类应该只有一个发生变化的原因。所谓职责指类变化的原因,单一职责指的是一个类或者模块应该有且只有一个改变的原因。

原理:如果一个类所承担的职责过多,一个职责的修改,可能会削弱或抑制这个类完成其他职责的能力。其核心为解耦与增强内聚性。
理解:在java开发中,每一个类只应该实现一个功能模块,每一个类下面的方法只应该实现该功能模块下的功能点。


 开闭原则(OCP)Open Close Principle

软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是,对于修改是封闭的。

梅耶开闭原则:一个类的修改只应该因错误而修改,新的或者改变的特性通过新建不同的类去实现。新建的类通过继承的方式来重用原类的代码。衍生的子类可以或不可以拥有原类相同的接口。

理解: 开闭原则可以通过继承实现重用,但是接口的实现不需要。对已经实现的接口修改是封闭的,新的实现不需要实现原有的接口。


 里氏替换原则(LSP)Liskov Substitution Principle

面向对象的三大特性是封装,继承,多态。里氏替换原则原则主要体现继承与多态,任何基类可以出现的地方,子类一定可以出现。当衍生类替换掉基类,而软件单位的功能不受影响时,基类才能被复用,衍生类也能够在基类的基础上添加新的行为(功能)。

理解:通过子类继承父类,子类可以替换父类,而父类无法替换子类。


 依赖倒置原则(DIP)Dependence Inversion Principle

程序依赖于抽象接口,而非具体实现。简单来说,对抽象编程可以降低客户与实现模块间的耦合。

原由: 面向过程的开发,上层调用下层,上层依赖下层,下层变动会引起上层的变动。而面向对象的开发,用户程序依赖于抽象,实现细节也依赖于抽象,即使实现细节变化,只要抽象不变,客户程序就不需要变化。
理解: 通过对抽象接口的实现,用户层只需要关心接口调用的返回结果,并不关心接口的具体实现。


 接口隔离原则(ISP)Interface Segregation Principles

客户端不应该依赖于它不需要的接口,类与类之间的依赖应该建立在最小接口上。

原由: 一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。
理解: 对于每个角色,它们所依赖的功能接口不同,针对每一个角色建立一个接口,接口只有该角色所需要的功能接口,通过新建一个类去实现所有角色的接口功能,以此实现接口隔离。


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

迪米特法则又称最少知识原则(LKP)Least Knowledge Principle

一个对象应该对其他对象有更可能少的了解。即一个软件实体应当尽可能少的与其他实体发生相互作用。每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

理解:一个类应该与其他类不存在联系,若需要联系,需要中间类进行协调。原则体现于设计模式中的门面模式与中介模式。
具体体现:

  1. 优先将类设置成不变类
  2. 尽量降低一个类的访问权限
  3. 谨慎使用Serializable
  4. 尽量降低成员的访问权限

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

合成与聚合都是关联的特殊种类,其中合成是值的聚合,而聚合是引用的聚合,其中合成又称为组成。

聚合:用来表示“拥有”关系或者整体与部分关系。代表部分的对象有可能会被多个代表整体的对象所共享,而且不一定会随着某个代表整体的对象被销毁或破坏而被销毁或破坏,部分的生命周期可以超越整体。
合成:更强的拥有关系。在合成的关系中,整体与部分的生命周期一样。

依赖:依赖是类与类之间的连接,表示一个类依赖于另外一个类的定义。依赖仅描述了类与类之间的一种使用与被使用的关系,在Java中体现为局部变量、方法的参数或者是对静态方法的调用。
关联:依赖是类与类之间的连接,表示一个类依赖于另外一个类的定义。依赖关系仅仅描述了类与类之间的一种使用与被使用的关系,在Java中体现为局部变量、方法的参数或者是对静态方法的调用。


为何使用合成/聚合复用,而不使用继承复用?
合成/聚合复用

由于合成或聚合可以将已有对象纳入到新对象中,使之成为新对象的一部分,因此新对象可以调用已有对象的功能。

优点:

1.通过接口实现对成分对象的存取。
2. 黑箱复用,成飞对象的内部细节对新对象不可见。
3. 支持包装,且所需依赖较少。
4. 每一个新类可以将焦点集中与一个任务(功能)上。
5. 可以在运行时间内动态进行,新对象可以动态地引用与成分对象类型相同的对象。

使用场景: 一个角色得到了更多的责任,那么可以使用合成/聚合关系将新的责任委派到合适的新的对象。然而通过此方式,会有较多的系统需要去管理。

继承复用

继承复用通过拓展基类实现新的功能,子类通过拓展属性与方法来拓展基类的实现。继承主要是类型的复用。
优点: 更易实现新的功能,修改与拓展原有的实现。
缺点:

1.破坏包装。基类实现细节对于子类透明。
2.基类实现改变影响子类。基类发生改变时,改变会传导到一级级的子类。
3.从基类继承而来的实现是静态的,不能在运行时发生变化。

由于继承复用有以上的缺点,所有尽量使用合成/聚合而不是继承来达到对实现的复用,是非常重要的设计原则。

你可能感兴趣的:(学习要点总结)