一、单一职责原则(SRP)

一个类而言,应该仅有一个引起它变化的原因,如果你能想到多于一个的动机去改变一个类,那么这个类具有多于一个的指责.应该把多于的指责分离出去,分别再创建一些类来完成每一个指责.

二、开闭原则(OCP)

钻研OO设计模式有一段时间了,可是天生愚笨,总是不得真谛,于是想是不是该跳出来仔细的想一想了呢?为什么需要设计模式?GoF的23设计模式的设计原则是什么呢?在查阅了一些资料后,仿佛有了一些感觉,其实设计模式的原则是OOD的原则,或者说设计模式是为了达到OOD的远景而提出的,所以正真的想掌握OO的精髓,那么学习设计模式是好的途径,而想真正掌握设计模式的精髓,那麽必须好好的理解一下OOD的设计原则,这篇文章关注的只是其中的一个原则--OCP。下面通过引用CSDN上Health King的专栏的一篇我认为比较好的关于OCP原则的文章开始我们的认识OCP之旅吧!

     原文链接:http://blog.csdn.net/kxy/archive/2005/06/27/405013.aspx

     在继续《设计模式精解》这本书之前,我们来学习些OOD的一些设计原则。这些原则在提高一个系统可维护性的同时,提高这个系统的可复用性他们是一些指导原则,依照这些原则设计,我们可以有效的提高系统的复用性,同时提高系统的可维护性。

     这些OOD原则的一个基石是“开-闭原则”(Open-Closed Principle OCP)。这个原则早是由Bertrand Meyer提出,英文的原文是:Software entities should be open for extension,but closed for modification。意思是说,一个软件实体应当对扩展开放,对修改关闭。也是说,我们在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,换句话说是,应当可以在不必修改源代码的情况下改变这个模块的行为。

     满足OCP的设计给系统带来两个无可比拟的优越性:
     通过扩展已有的软件系统,可以提供新的行为以满足对软件的新需求,使变化中的软件系统有一定的适应性和灵活性。
     已有的软件模块,特别是重要的抽象层模块不能再修改,这使变化中的软件系统有一定的稳定性和延续性。

     具有这两个优点的软件系统是一个高层次上实现了复用的系统,也是一个易于维护的系统。那么,我们如何才能做到这个原则呢?不能修改而可以扩展,这个看起来是自相矛盾的。其实这个是可以做到的,按面向对象的说法,这个是不允许更改系统的抽象层,而允许扩展的是系统的实现层。

解决问题的关键在:抽象化。我们让模块依赖于一个固定的抽象体,这样它是不可以修改的;同时,通过这个抽象体派生,我们可以扩展此模块的行为功能。如此,这样设计的程序只通过增加代码来变化而不是通过更改现有代码来变化,前面提到的修改的副作用没有了。

   “开-闭”原则如果从另外一个角度讲述,是所谓的“对可变性封装原则”(Principle of Encapsulation of Variation, EVP)。讲的是找到一个系统的可变因素,将之封装起来。在我们考虑一个系统的时候,我们不要把关注的焦点放在什么会导致设计发生变化上,而是考虑允许什么发生变化而不让这一变化导致重新设计。也是说,我们要积极的面对变化,积极的包容变化,而不是逃避。

     [SHALL01]将这一思想用一句话总结为:“找到一个系统的可变因素,将它封装起来”,并将它命名为“对可变性的封装原则”。

    “对可变性的封装原则”意味者两点:
     一种可变性应当被封装到一个对象里面,而不应当散落到代码的很多角落里面。同一种可变性的不同表象意味着同一个继承等级结构中的 具体子类。继承应当被看做是封装变化的方法,而不应当是被认为从一般的对象生成特殊的对象的方法(继承经常被滥用)。
     一种可变性不应当与另外一种可变性混合在一起。从具体的类图来看,如果继承结构超过了两层,那么意味着将两种不同的可变性混合在了一起。

    “对可变性的封装原则”从工程的角度说明了如何实现OCP。如果按照这个原则来设计,那么系统应当是遵守OCP的。但是现实往往是残酷的,我们不可能的遵守OCP,但是我们要向这个目标来靠近。设计者要对设计的模块对何种变化封闭做出选择。

     好了,上面是引用的全文了。那麽在实际设计和开发之中,我们该如何重构我们的设计和代码呢?
     答案是:抽象(Astraction)、多态(Polymorphism)、继承(Inheritance)、接口(Interface)。利用这些可以让我们去实践OCP了,这样会让我们的设计符合OCP,符合该法则便意味着高等级的复用性(Reusability)和可维护性(Maintainability)。当然我们也有很多的设计模式可以利用来很优美的解决如何封装变化等问题,但是不要忘了,设计模式的基础也是抽象(Astraction)、多态(Polymorphism)、继承(Inheritance)、接口(Interface)啊。还是从简单开始吧,千里之行,始于足下...