面向对象的设计原则

来源:互联网 发布:手机淘宝详情添加视频 编辑:程序博客网 时间:2024/05/01 01:54

1、单一职责原则(Single-Resposibility Principle)

    单一职责原则说的是一个类应该只做一件事,应该只有这件事的变化会引起它的变化。一个类的职责如果越多,那么就表示可能引起它变化的原因越多,众多的职责汇聚在一个类里必然导致的结果是牵一发而动全身,耦合度的增大和内聚度的降低。这就好比一个小组中每个人都承担了不同的职责,责任到人便于管理,如果一个人身兼数职,那么他的压力就会变大,他出错的概率就会变大,如果这个人请假回家了,那么就会导致大量工作的停步不前。

总结:将一个类的功能单一化,不同的功能分由不同的类来完成。

2、开放封闭原则(Open-Closed principle)

    开闭原则讲的是软件实体应该是可扩展而不可修改的。也就是,对扩展开放,对修改封闭的。当有新需求加入的时候只需要增加一部分新需求代码不用修改原有代码就可以提供支持。要达到不修改原有代码就可以无缝扩展的要求,就需要我们在设计的时候不依赖于具体的实现而是依赖于抽象(java里的接口和抽象类),依赖的只是抽象,无论实现类是何种模样,当我们依赖抽象屏蔽具体实现编程的时候,系统便不知道了具体实现的形态,这个时候再进行扩展将是无缝的、很自然的。依赖抽象编程的另一个原因是抽象是稳定的,是比任何一个具体实现都稳定的,如果抽象都不稳定了那么实现又有何稳定可谈?一个软件可能已经无法再修改一个它的源码,它可能只剩下一些二进制的可运行的文件,这个时候如果这个软件系统的设计良好的遵循了开闭原则,那么我们依然可以在无法修改原有二进制文件的基础上对其进行扩展。

总结:核心控制逻辑面向抽象设计,与具体的实现完全隔离,自由扩展实现而无需修改核心。

3、里氏替换原则(Liskov-Substituion Principle)

    其核心思想是:子类必须能够替换其基类,即父类引用指向子类对象的时候不会影响原先指向父类时候的任何功能。之所以要遵循这一原则是为了保证继承复用的可靠性,进而保证系统的稳定性,想想看如果一个父类的功能被子类任意复写和覆盖,那么原先持有父类引用(实际指向的是子类对象)在调用这个方法的时候可能会发生意想不到的致命错误。所以违反里氏替换原则的扩展不是完美的扩展是需要修改原父类(可能是个抽象)的方法的,进而就违反了开闭原则,所以历史替换原则可以保证良好的扩展性,同时基于多态的机制里氏替换原则不仅减少了代码的冗余而且避免了运行期的类型判断。要遵循这一原则需要做到以下几点:

1、子类可以实现父类的抽象方法,但尽量不要去覆盖父类的非抽象方法。

2、当子类的方法重载父类的方法时,方法的形参不能比父类的严格。

3、当子类的方法实现父类的抽象方法时,方法的返回值不要比父类更宽松。

总结:科学使用继承机制,保证系统的稳定和规范(结构规范和代码规范),同时对开闭原则提供支持。

4、依赖倒置原则(Dependecy-Inversion Principle)

    依赖倒置原则应该是面向对象编程中最核心的原则,其它四个原则都完全支持依赖倒置原则,这个核心原则说的是类与类之间模块与模块之间不应该有直接依赖,他们直接应该通过抽象来产生依赖,抽象是制约性的它不依赖于具体实现细节,实现细节依赖于抽象。依赖倒置使得原先的硬性依赖得以解耦,使得我们的软件系统设计层次结果和衍生规律更加清晰明了。为何叫依赖“倒置”,因为之前的编程各模块之间,类与类之间,都是硬性的实实在在地从调用者到被调用者(从上到下)的依赖关系,这种顺势而下的依赖我们称之为“依赖正置”,而依赖倒置正好相反,我们不在顺势而下直接依赖实现类本身,而是依赖实现类的上层抽象,各种原先的硬性依赖都指向都改向指到了各自上层的抽象,这就是“依赖倒置”。因为依赖的都是抽象,自然耦合度就低,因为依赖了抽象,实现类便可以自由的扩展,扩展性就好。既然依赖倒置有这么大的优势,如何才能做到依赖倒置呢?这就需要对业务系统有整体的正确的把握,对业务有敏锐的抽象能力,以下几点可以帮助我们实现业务抽象:

1、每个类尽量都有接口和抽象类,或者抽象类和接口都有。

2、变量的表面类型尽量是接口或者是抽象类。

3、任何类都不应该从具体类派生。(在无法获取高层抽象时例外)。

4、尽量不要覆写基类已经实现好的方法。(里氏替换原则的体现)。

总结:万物生于抽象,用于抽象,抽象下众生平等,万物再生再用,抽象自岿然不动!


5、接口隔离原则(Interface-Segregation Principle)

    在了解了单一职责原则之后我们知道了应该尽量把不同的职责分配给不同的类去完成,相同地,接口的设计也较为类似,接口隔离原则约束的是我们应该使用专门的接口去完成特定的工作,这个工作会使用到这个接口中所有的方法,而不应该使用所谓的“大众接口”、“万用接口”去完成某些特定工作,这样会造成接口功能的污染和浪费,因为这个大杂烩接口中的某些方法可能永远都不被使用,另外,如果我们完成这一特定工作使用这个接口的话就需要实现里面的所有的方法,这无疑是一项只有苦劳没有功劳的工作,而且这个接口因为担任了很多职责,当它因为其他职责而发生改变的时候,那么这个接口担负的所有职责的这个接口的实现类都会无辜的被牵连而改动,这种代价是巨大的。要遵循接口隔离原则一点是要尽量使用专门接口完成特定的工作,而不参与别的工作,把“胖接口”隔离为一个一个完成特定工作的小接口。如果遇到多个接口工作类似等情况可以考虑使用接口继承!

总结:接口也要遵循单一职责原则!

原创粉丝点击