sharplife


software is a artwork, also make the life better !!!
  首页  :: 联系 :: 订阅 订阅  :: 管理

敏捷实践:SRP OCP LSP DIP ISP原则

Posted on 2006-12-09 13:39  sharplife  阅读(1817)  评论(0编辑  收藏  举报

    敏捷开发提倡简单设计的实践,“并在实现新需求时抓住机会改进设计”以对同类性质的改动封闭,做到由需求的变化驱动设计的进化(我们不能因为设计的退化而责怪需求的变化),同时经验在此起到十分重要的作用,如有经验的设计人员可以凭经验在初始设计时做出必要的抽象来满足ocp原则等,或是在需求变动时确定系统所需的抽象(所需的封闭),当然应及早的刺激这种变化的出现(如测试驱动的开发方法)。

  OOD承诺了一系列的好处(灵活性可重用性可维护性),用OO语言设计开发,若要方便的得到这些所谓的好处,有一系列的原则是要遵循的,如SRPOCPLSPISP等。

   SRP(单一职责原则)维护类的简单性,类不应承担一个以上令其变化的原因,否则应考虑分离并重新构造类,但如果的应用的变化方式总是导致类中的职责同时变化,却没必要分离他们

  Ocp(开闭原则)使OO系统做到对扩展开放,对修改封闭。OCP的遵循关键在于抽象,其主要实现方式有:定义接口描绘所需的操作,client只需关注接口的调用,子类型可以以任何其选择的方式实现接口,即所谓的stategy模式,或者定义抽象类并于其中实现公共操作,个性操作定义为abstractvirtual,由子类型负责个性化实现,通过此两法,将功能的通用部分和实现细节分离出来。当然,设计人员应该确定(猜测或凭经验)系统对哪种变化做到封闭,因为不可能对所有变化做到封闭,如《敏捷模式实践》中提到shape类型排序处理问题,为做到对排序安排(或变动)的封闭(使得各子类型间无需相互知晓,也可以做到自由安排排序顺序),选择使用“数据驱动”的方式(即单独构造结构表示排序安排—其中以子类类型在结构中的排列位置表先后),于shape基类中实现一次Precedes操作即可,子类型无需分别实现。OCP作为OOD核心所在依赖抽象来实现,但敏捷设计(或者说好的设计)拒绝不成熟的抽象,程序仅应对频繁变化的部分做出抽象。

  Liskov替换原则是使得ocp成为可能的原则之一,强调“子类型subtype必须能够替换掉它们的基类型basetype”,控制OO的继承关系安排,在OODis-a来确定类间的继承关系,LSP指出这种is-a关系是就行为方式(即类的各操作)而言的,而行为方式是可以合理假设的,是客户程序所依赖的。为遵循LSP,可借用DBCdesign by contract)的操作前置条件和后置条件,“要使操作得以执行,前置条件必须为真,执行完毕后,该操作要确保后置条件为真”(为每个方法注明其前置和后置条件十分有帮助),如此,则“在重新声明派生类中操作时,只能使用相等或更弱的前置条件来替换原始的前置条件,只能用相等或更强的后置条件来替换原始的后置条件”(interface和其实现类间 抽象方法和其实现 此二者一定满足前述条件)。同时亦可用前述ocp遵循所用的二模式使设计符合LSP,另外子类型中的异常抛出应考虑在遵循LSP的范围内。

  关于提取公共部分的设计工具:“提取公共职责放入超类中,稍后添加的新的子类型可能会以新的方式支持同样的职责,此时原来的超类可能会是一个抽象类”。

    DIP(依赖倒置原则),作为framework的设计核心,其相对于传统软件设计而言,通常(传统)软件设计中采用结构化设计用高层模块直接调用底层模块,这样高层模块将严重依赖于底层模块的变动,在OOD中通过为高层模块定义所需使用的服务接口,底层模块现实这样的接口,高层模块通过抽象接口使用下一层strategy模式所声明的),如此看来接口的拥有者一般是其使用者而非其实现者。通常为了满足DIP-良好OOD的基本底层机制,我么需要找出系统中潜在的抽象,而抽象通常是那些不随具体细节变化而变化的东东。

    ISP接口隔离原则,如SRP维护类的简单性一样,ISP用于维护接口的简单和必要性,因为接口是为客户调用的,因此其应该是“大小尺寸合适的”,“胖”接口显然对调用者造成累赘,ISP则用于将“胖”接口分离成多个合适的接口。

    当然,在系统设计实现中要做到这些并非容易,单单知道其存在未必做得到将其实现到系统中,开发经验的积累同样重要,但早些知道存在个意识并在做时将其考虑进去,也是积累,慢慢来吧,n多事要做呐。

  ——敏捷软件开发:原则 模式与实践