明天就是五一了,先祝各位老友们五一快乐。
      公司终于让我做设计了,哈哈,不过是详细设计,还没有到系统的份上。不还我还是比较满意的,以前有辞职的想法,现在,怎么也要等这个项目做完之后再说了。
      这段时间一直在研究“面向对象设计的原则”,以下是学习的一点经验:
      1.类的设计原则
         在网上,一般认为灯的设计原则有五类,如下:
   1)SRP,单一职责原则,一个类应该有且只有一个改变的理由。 
                  所谓单一职责原则,就是就一个类而言,应该仅有一个引起它的变化的原因。换句话说,一个类的功能要单一,只做与它相关的事情。
  这个原则是最简单、最容易理解,却是最不容易做到的事情。这个原则的道理谁都理解,可是在实践中呢?

  我们来看一个例子:

if(action.equals("load")&&tab.equals("1")){
request.setAttribute("tabId",tab);
form.set("tabId",tab);
speciManager.loadIncrement(actionForm, request, tab);
}
if(action.equals("Save")&&tab.equals("1")){
System.out.println("inter increment save action");
……
request.setAttribute("tabId",tab);
}
if(action.equals("load")&&tab.equals("2")){
request.setAttribute("tabId",tab);
form.set("tabId",tab);
speciManager.loadMeasureMent(actionForm, request, tab);
}
if(action.equals("Save")&&tab.equals("2")){
……
System.out.println("inter increment save action");
speciManager.loadIncrement(actionForm, request, tab);
form.set("tabId",tab);
request.setAttribute("tabId",tab);

}
  一看就知道这个类做了太多的工作,它既要load一个tab为1的页面和一个tab为2的页面;又要save一个tab为1页面和一个tab为2的页面。这个类的代码我只截取了里面很少的一部分,绝大部分的代码我都省略掉了。这段代码写到最后是越来越混乱,直到最后失败。

  对照着这个例子,我们再来分析一下为什么要遵守单一职责愿则:

  第一、有助于我们分析和编码的思路的清晰。当你的代码里有了三层或以上的if语句或for语句的嵌套的时候,你不要跟我说,你已经把问题分析得很清楚了。多层嵌套的if或for语句只能说明你还没有把问题分析清楚。

  第二、使我们的编码、测试和维护变得简单。

  第三、将一个个复杂的问题简单化以后,易于代码的重用。当你的代码的多个功能搅和在一起的时候,你是没办法考虑代码的重用的,因为你的每一处代码都有不同。

  第四、易于系统的扩展。 
 2)OCP,开放封闭原则,你应该能够不用修改原有类就能扩展一个类的行为。 
               “开一闭”原则讲的是:一个软件实体应当对扩展开放,对修改关闭。 这个规则说的是,在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。 从另外一个角度讲,就是所谓的“对可变性封装原则”。“对可变性封装原则”意味着两点: 1 .一种可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里面。同一种可变性的不同表象意味着同一个继承等级结构中的具体子类。 2.一种可变性不应当与另一种可变性混合在一起。即类图的继承结构一般不应超过两层。 做到“开—闭”原则不是一件容易的事,但是也有很多规律可循,这些规律同样也是设计原则,它们是实现开—闭原则的工具
  3)  LSP,Liskov替换原则,派生类要与其基类自相容。 
                   里氏代换原则:就是子类代替父类,程序或者代码的行为不变。例如如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有对象o1都换成o2时,程序P的行为没有变化,那么类型T2是T1的子类型。 即如果一个软件实体使用的是基类的话那么也一定适用于子类。但反过来的代换不成立。 如果有两个具体类A和B之间的关系违反了里氏代换原则,可以在以下两种重构方案中选择一种: 1 创建一个新的抽象类C,作为两个具体类的超类,将A和B共同的行为移动到C中,从而解决A和B行为不完全一致的问题。 2 从B到A的继承关系改写为委派关系。 
 4) DIP,依赖倒置原则,依赖于抽象而不是实现。 
                  依赖倒转原则讲的是:要依赖于抽象,不要依赖于具体。即针对接口编程,不要针对实现编程。针对接口编程的意思是,应当使用接口和抽象类进行变量的类型声明、参量的类型声明,方法的返还类型声明,以及数据类型的转换等。不要针对实现编程的意思就是说,不应当使用具体类进行变量的类型声明、参量的类型声明,方法的返还类型声明,以及数据类型的转换等。 依赖倒转原则虽然强大,但却不易实现,因为依赖倒转的缘故,对象的创建很可能要使用对象工厂,以避免对具体类的直接引用,此原则的使用还会导致大量的类。维护这样的系统需要较好的面向对象的设计知识。 此外,依赖倒转原则假定所有的具体类都是变化的,这也不总是正确的。有一些具体类可能是相当稳定、不会发生变化的,消费这个具体类实例的客户端完全可以依赖于这个具体类。
  5) ISP,接口隔离原则,客户只要关注它们所需的接口。 
                  接口隔离原则讲的是:使用多个专门的接口比使用单一的接口要好。从客户的角度来说:一个类对另外一个类的依赖性应当是建立在最小的接口上的。如果客户端只需要某一些方法的话,那么就应当向客户端提供这些需要的方法,而不要提供不需要的方法。提供接口意味着向客户端作出承诺,过多的承诺会给系统的维护造成不必要的负担。 

         2.包原则

      REP,重用发布等价原则,重用的粒度就是发布的粒度。 
      CCP,共同封闭原则,包中的所有类对于同一类性质的变化应该是共同封闭的。  
      CRP,共同重用原则,一个包中的所有类应该是共同重用的。 

      3  .包之间的耦合性原则 
       ADP,无环依赖原则,在包的依赖关系图中不允许存在环。 
      SDP,稳定依赖原则,朝着稳定的方向进行依赖。 
      SAP,稳定抽象原则,包的抽象程度应该和其稳定程度一致。