设计模式六大原则

来源:互联网 发布:知乎俄罗斯模特在中国 编辑:程序博客网 时间:2024/06/06 04:07


   没有规矩,不成方圆。设计模式也有原则。设计模式有七个原则,分别是:单一职责原则(Single Responsiblity Principle SRP)开闭原则(Open ClosedPrinciple,OCP)、里氏代换原则(Liskov Substitution Principle,LSP)、依赖倒转原则(DependencyInversion Principle,DIP)、接口隔离原则(Interface SegregationPrinciple,ISP)、合成/聚合复用原则(Composite/Aggregate ReusePrinciple,CARP)、最小知识原则(Principle of Least Knowledge,PLK,也叫迪米特法则)。

   在这里先介绍常见的六种原则。


单一职责原则



        这个原则说起来很简单,就是万物都有极限,一个人,长得特别高可能灵活性就会差一点,穿衣服用布料就会多一点,睡觉用的床就会长一点。这都是由于某个特点带来的属性。他不可能每一样属性都特别好特别完美。这就是单一职责原则的基本属性。


        在计算机里,就是分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。


       那么什么时候用这个原则呢?


        一个类如果只负责一个职责,那是符合单一职责原则的。如果之后由于某种需求,需要将这个职责分为更细的东西,这个时候这个类就会负责多个职责,就需要将职责分离开。


        好处在哪儿?


        降低逻辑的复杂度。因为每个类职责都很单一。
       提高系统可维护性。
       变更方便。修改一个类的时候,可以降低对其他功能的影响。
       高内聚,低耦合。



开放封闭原则



        这个原则是学习设计模式的一个重要因素。我们平时用的软件都需要不断地更新,增加或者优化功能才能保证用户持续的使用。如果每次的优化都需要改动整个程序,那工作量就会很庞大。所以开放封闭原则的好处就来了。


       开放封闭原则就是说软件的实体(类、模块、函数等)可以扩展,但是不能修改。也就是说,要扩展和改变一个程序的功能,可以增加代码,但是不能改变源码。


       好处是什么?


      也就是面向对象的四大好处:可维护、可扩展、可复用、灵活性好。



依赖倒转原则


        高层模块不应该依赖底层模块,他们都要依赖抽象,抽象不应该依赖细节,细节应该依赖抽象。
        举个栗子,之前塞班系统的手机有一个大麻烦,就是手机里的软件是根据手机的品牌以及型号去做的,所以当看到别人的手机里有好玩的游戏,还是比较无能为力的。而现在,如果想一起开黑,不管什么牌子的手机,装一个软件大家就可以一起玩了。所以,编程要针对接口,而不是针对实现。


        什么时候用?
        如果类A是高层模块,它依赖类B,并且需要通过C来实现同样功能就要改动A的代码。可以将A改成接口,让B和C各自实现接口。A通过接口间接地和B、C发生联系。


        好处是什么?
        它的好处就是减少类之间的耦合性,减少并行开发引起的风险,提高代码的可读性和可维护性。


里氏代换原则


        说到依赖倒转原则就不得不提里氏代换原则:子类型必须能够替换掉他们的父类型。
        如果在一个软件实体中,使用的是父类的话,那就一定适用于子类,并且察觉不出父类和子类对象的区别。在软件里就将父类全都替换成它的子类。


        有了这个原则,让继承复用成为了可能,只有当子类替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,儿子类也能在父类的基础上增加新的行为。




最少知识原则(迪米特法则)


        这个法则让我想起一句话:两耳不闻窗外事,一心只读圣贤书。也就是说,这个人只有一件事可做,就是读书。虽然在咱们看来,这种生活方式不值得推崇,但是头脑简单的计算机却很喜欢收到这种命令。


        如果两个类不必直接通信,那这两个类就不应当发生直接的相互作用,可以通过第三方来实现调用等等。




合成/聚合原则


        有人说,要尽量使用合成/聚合原则,尽量不要使用继承。但其实前面才说某个法则实现了继承复用,现在就尽量不要用继承复用,是不是有些费解?接下来来介绍一下,继承复用、合成以及聚合。

       

       1.继承复用

        

        继承是通过扩展一个已有对象的实现来得到新的功能,继承是类型的复用。

事物都有两面性,优点有可能同时成为缺点。因为继承复用中父类大部分功能会通过继承关系自动进入子类,所以新的实现会比较容易,但是会破坏封装。因为继承的出现,父类的实现细节都暴露给了子类。并且,一旦父类改变,子类就不得不改变,并且没有足够的灵活性。所以这是一种“白箱”复用。


       2.合成/聚合复用



       什么是合成?

     

        合成是一种强的拥有关系,比如人有胳膊,胳膊和人就是部分和整体的关系,如果没有人,胳膊也就不会存在。所以这两种关系的生命周期是相同的。


        什么是聚合?

        

        聚合表示一种弱的拥有关系,A对象可以包含B对象,但是B对象并不是A的一部分。比如人和人群,每个人都是独立的个体,人群可以有很多人,每个人都属于一个人群。

合成/聚合复用是将已有的对象纳入到新对象中,使之成为新对象的一部分,所以新对象可以调用已有对象的功能。



        使用合成/聚合复用时,新对象存取成分对象的唯一方法是通过成分对象的接口,成分对象的内部细节新对象是看不见的。并且这种复用所需的依赖较少,支持封装。当然这也衍生出了它的 缺点,因为这会造成对象特别多的现象,管理起来会稍微困难。
原创粉丝点击