您的位置:首页 > 其它

设计模式之1--五大原则

2016-03-21 12:20 387 查看
 之前我们讨论过面向对象的本质了,也就是为什么要有面向对象,人类看待世界的方式就是从各种不同的视角对事物进行各种层次的抽象,并在不同的抽象层次统一地对待这些事物。抽象的过程也就是寻找这些事物共同特性、本质特征的过程。这五大原则均由面向对象的本质衍生而来。

1. LSP The Liskov Substitution Principle 里氏替换原则
   里氏替换原则是指:“一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序的行为没有变化。”
   为什么要有里氏替换原则呢?从它的解释中不难看出,是为了在较高抽象层次统一对待该类型的所有子类。如:车是父类,其子类有自行车、摩托车、汽车,汽车又有子类:客车、货车,客车又有子类:轿车和大客车。需要在“车”这个抽象层次进行统一对待,车要有“被驾驶”功能,那么,其所有的子类,无论是自行车、摩托车、轿车、大客车或者货车,都需要能“被驾驶”,而对待“车”的这个主体只需要对“车”进行“驾驶”,而无需关心到底是哪种车。但是,如果其中某一个子类的“被驾驶”功能表现跟其父类不一样,则会使进行“驾驶”的主体感到很意外,甚至出现事故。
   显而易见,违反里氏替换原则的设计将使得人们不能够在一个特定的抽象层次来对此类事物进行统一对待,是有违面向对象思想初衷的。

2. OCP The Open Closed Principle 开放封闭原则
   开闭原则是指:“一个软件实体应当对扩展开放,对修改关闭。”什么是扩展?什么是修改?扩展是指在上层设计时对该类事物的行为有了一定的定义和限制,但是依然为之后的变化留下了余地,当然,这个变化是受限的,是有一定预期的,其子类事物可以根据实际情况并按照该预期进行演变;修改是指改变已有事物的行为特性。
   事物是生存在一定环境之中并且与其他事物协同工作的,如果要修改一个已有事物的行为特性,将需要对所有与之直接或间接相关的所有事物相协调,并且还需要对之前已由该事物处理的结果作相应的调整,在复杂系统中,做到这点是非常困难的。往往的结果是解决了当前问题却引出了其他的问题。
   而扩展是有预期并且受到一定限制的。换句话说,子类的扩展是满足它的上层抽象对它的期望的。子类可以为了应对更具体的环境、做更具体的事情而有自己特有的动作,但是它的这些动作还是在完成上层抽象中所定义的行为。所以说,扩展是不影响人们在其抽象层次上统一对待该类事物的。
   总而言之,此原则就是说设计具体类不要影响人们对其抽象层次上的期待。

3. DIP The Dependency Inversion Principle 依赖倒置原则
   依赖倒置原则是指:“要依赖于抽象,不要依赖于具体。”这里的“倒置”是相对于以前的传统的结构化编程中,最上层的模块通常都要依赖下面的子模块来实现(也称为高层依赖低层)来说的。
   为什么要依赖抽象呢?因为抽象出来的是该类事物的共性与本质特征,这类事物就是做这些事情的,这些共性是稳定的。越高抽象层次上的特征就越稳定,而越具体的事物的特性则越容易发生变化。如:一个人较容易由喜好吃饼干而改为喜好吃蛋糕,但是作为抽象层次的人却难改变要吃饭的特性,凡是人都是要吃饭的。
   另一个例子是,不要因为你家的车是电动车而认为所有的车主在开车出门前都要先找好电动车充电站,因为别人家的车可能是汽油的。电动车是具体的一种车,它需要充电,而充电的地方不好找,所以在出门前需要确定好什么地方可以充电。如果依赖电动车的特点来判断所有车主的行为就有问题了,以汽油为燃料的车因为加油站很多,而且哪里都有,所以他们出门前不需要考虑这个问题。所以,“寻找电动车充电站”就不是所有车主要做的事情,其实,所有车主的共性仅仅只是“能驾驶他的车”。
   这个原则背后还隐藏着一层含义:人们需要搞清楚现在设计的行为比较适合在哪一个抽象层次进行。看看行为的主体与客体,主体的这个动作所对待的客体到底在哪个抽象层次?是人?还是学生?还是中学生?还是……?找到了适当的抽象层次,也就是找到了做这件事情的本质。

4. SRP The Single Responsibility Principle 单一责任原则。
   单一责任(职责)原则:“就一个类而言,应该仅有一个引起它的变化的原因。”这里的“引起它变化的原因”是什么呢?是主体(它的使用者)对待它的方式,或者说,是主体对它的期望。如果一个类要被用作多种用途,就意味着它的主体不止一个,至少,它对于它的主体来说,具有不止一种意义。当主体对它的期望发生变化,它就会改变它的行为方式。为了迎合主体对它的一种期望,它就有了一个发展变化的方向。有多种期望加于它,它就需要兼顾各种对它的期望,在作具体实现时受到多种限制与影响,有些甚至互相矛盾,如此造就了一些扭曲的设计,这样的设计在后续的维护、变化中不容易理解,更容易造成错误。简单来说,就是当你为了迎合一个方面的期待来作出变化时,很容易就影响了另一个方面对它的期待。用更容易理解的方式说明就是,当一个职员只有一个上司时会比较容易伺候,而如果有多个上司同时指使他工作的时候就较难伺候了。
   这个原则同时体现了“简单是美”的哲理,越是简单的越是能够专注,也越为牢固(大家都知道多功能工具比单功能工具更容易坏的道理)。遵循这个原则,我们往往会更清晰地划分职责,将一件事情划分为各自独立发展变化(正交)的几个方面,这对我们看待整个问题域有着很大的帮助,促使系统更加稳定。

5. ISP The Interface Segregation Principle 接口分离原则
   接口分离原则也叫接口隔离原则,是指:“不应该强迫客户端依赖于他们不会使用的接口。”这里的“客户端”就是利用该事物的主体,“接口”就是对该类事物的抽象。这个原则体现的是我们对事物的抽象需要“恰到好处”。怎么才是恰到好处呢?所谓“增之一分则太肥,减之一分则太瘦”。如前文所说,从一个视角看待某一类事物,看到的是应该是它们在这件事情上的共性和本质属性。与此有关的要看全,与此无关的则不要关注。关注了多余的跟没有看全一样,所谓“过犹不及”。为什么呢?因为关注了多余的特性就一定不是在这件事情上的本质特性,它就不是最稳定的,依赖这样不稳定的特性会容易会造成整个系统的脆弱。比如,你需要的就是一个能装水的容器来装水,那么这个事情的本质就是“装水”,我们只需要关注这个容器的“装水”特性就好了,但如果我们还关注并依赖了一个非本质的特性“美观”,也就是说,我们要求这个容器既需要能装水,还需要美观。如此,一些设计非常精良、并且适合于某些特殊条件(如:零下300摄氏度)但却并不美观的容器就无法使用了。甚至,由于某一天“美观”的评价标准改变了将导致我们现有的所有容易都需要重新改造。
   所有事物都是存在于上下文之中,依赖于环境,并且与其他事物协同工作的。但是,它对于环境、其他事物的依赖越少,它就越稳定;与依赖相对,对环境与其他事物的承诺越少,该事物也越稳定。整个系统的稳定性也是取决于此。这个原则其实是事物稳定性原理的体现。

   遵循这五大原则能够使我们的设计更加稳定与优雅,面向对象设计有许多模式,这些模式也是在一定情境下遵循这些原则的结果,之后我们将一起来讨论这些模式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息