分享

面向对象设计原则总结

 Baruch 2017-08-04

参考博文:http://www.cnblogs.com/shaosks/category/351488.html

面向对象设计的原则主要有:单一职责原则,开放封闭原则,里氏替换原则,依赖倒置原则,迪米特法则,合成/聚合复用原则。下面将对每个原则做一个学习理解与总结,加深对面向对象的理解,促进工作中对这些原则的运用。

1、单一职责原则(Single Responsibility Principle  SRP)一个类只做一件事情

There should never be more than one reson for a class to change。也就是说引起一个类改变的原因只能有一个,一个类承担的职责过多应进行分离,使程序设计达到高内聚低耦合的原则。从而使一个功能的改变只需要修改一个类而不影响到其他的功能。例如作者所说的调制解调器,应该将连接和数据传送两个功能分开抽象出两个接口,而调制解调器同时实现这两个接口实现链接和数据传送的功能,因此当链接的功能改变时对数据传送功能没有产生任何影响。

单一职责原则优点:降低类的复杂性,提高可维护性,提高可读性,降低需求变化带来的风险。

2、开放封闭原则(Open-Closed Principle OCP)面向抽象编程

开放封闭原则是所有面向对象原则的核心,要求软件实体应对扩展开放,对修改封闭。软件设计本身追求的目标就是封装变化,降低耦合,而开放封闭原则正是对这一目标的直接体现。

开放封闭原则的实现:实现思想就是对抽象编程,而不是对具体编程,因为抽象相对稳定。让类依赖于固定的抽象,所以对修改就是封闭的;通过面向对象的继承和多态机制,可以实现对抽象体的继承,通过重写其方法来改变固定的行为,实现新的扩展方法,所以对于扩展就是开放的。

开放封闭主要是两方面,对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况;对修改封闭,意味着一旦设计完成,就可以独立其工作,而不要对类进行任何修改。

如何实现耦合度和灵活性兼得呢?那就是抽象,将业务功能抽象为接口,当业务依赖于固定的抽象时,对修改就是封闭的,而通过继承和多态,从抽象体中扩展出新的实现,这就是对扩展的开放。这样当业务变成时,只需要修改对应的业务实现类即可,其他不相干的业务就不必修改。当业务增加时,只需要增加业务的实现就可以了。

拒绝滥用抽象,只将经常变化的部分进行抽象。

3、里氏替换原则,(Liskov Substitution Principle LSP)子类可以替代父类

里氏替换原则讲的是基类和子类的关系,指任何基类可以出现的地方,子类一定可以出现。继承必须保证超类中所拥有的性质在子类中仍然成立,也就是说子类必须能够替换成它们的基类。Liskov替换原则主要用来约束继承的泛滥问题。

如果子类不能完整的实现父类的方法,建议断开父子继承关系,使用依赖,聚合,组合等关系。

采用里氏替换原则的目的时增加程序的健壮性,需求变更时也可以保持良好的兼容性和稳定性,即使增加子类,原有的子类可以继续运行。在实际项目中,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类完成不同业务逻辑。


4、依赖倒置原则(Dependence Inversion Principle DIP)依赖于抽象不依赖于具体

依赖倒置原则就是高层模块不应该依赖于底层模块,而这都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。

抽象:即抽象类或接口,是不能实例化的

细节:即具体的实现类,实现接口或者继承抽象类所产生的累,可通过关键字new 实例化。


在实际编程中我们需要做到三点:

  • 底层模块尽量都要有抽象类或者接口,或者两者都有
  • 变量的声明类型尽量是抽象类或者接口
  • 使用继承时遵循里氏替换原则

面向过程的开发是上层调用下层,上层依赖于下层,当下层剧烈变化时,上层也要跟着变化,这样导致模块的复用性降低而大大提高了开发成本。面向对象开发解决了这个问题,一般情况下,抽象的变化概率较小,让用户依赖于抽象,实现细节也一俩与抽象。即使实现细节不断变化,只要抽象不变,客户程序就不需要变化,这就大大降低了客户域实现细节的耦合度。

总之,一个应用的主要策略及业务往往集成咋高层模块中,但是这些模块依赖于底层模块时,底层的修改将直接影响到高层模块,迫使它们也改变,这是不科学的。应该时处于高层的模块迫使底层的模块发生改变,处于高层的模块应该优先于底层的模块,无论如何高层模块也不应该依赖于底层模块,而且我们能够服用的时高层的模块,只有高层模块独立于底层模块时,服用才有可能。最终,高层次的模块不依赖于底层的模块,它们都应该依赖于抽象。抽象不应该依赖于具体,具体应该依赖于抽象。

5、迪米特原则(Law of Demeter)又叫最少知识原则(Least  Knowlege Principle LKP)对象与对象之间尽可能少的交互

面向对象来说,一个软件实体应尽可能少的与其他实体发生相互作用,降低类之间的耦合,每个类都尽量减少对其他类的依赖,这样做的结果是很容易实现模块的相互独立,但可能造成一个后果,系统中存在大量的中介类,这些类用来传递类之间的相互调用关系,一定程度增加了系统复杂度。

迪米特法则在设计模式中的门面模式(Facade)和中介模式(Mediator)中得到应用。


6、合成复用原则又称组合/聚合服用原则(Composite Reuse Principle CRP)复用时尽量使用组合/聚合关系(关联关系),少用继承。

合成复用原则就是在一个新的对象里通过关联关系来使用一些已有的对象,使之成为新对象的一部分,新对象通过委派调用已有对象的方法达到服用功能的目的。

在面向对象的程序设计中,可以通过两种方法在不同的环境中服用已有的设计和实现,即通过组合/聚合或通过继承,但首先应考虑使用组合/聚合,组合/聚合使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少,其实考虑继承,使用继承时严格遵循里氏替换原则,有效使用继承会有助于对问题的理解,降低复杂度,而滥用继承反而增加系统构建与维护难度以及系统的复杂度,因此需要谨慎使用继承复用。

一般而言,如果两个类之间时“Has-a”的关系应使用组合或聚合,如果是“Is-a”的关系使用继承。

合成复用可以在运行时动态进行,新对象可以动态的引用与成员对象类型相同的其他对象。


总结,通过以上对面向对象程序设计中原则的梳理,希望以后代码过程中能得到更广泛的应用,提高代码质量。




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多