敏捷软件开发

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

敏捷软件开发:SRP单一职责原则

(2009-03-24 20:30:24)

转载

标签:

it

这条原则实际就是体现内聚性原则的体现,一个模块的组成元素之间的功能相关性。把内聚性概念扩展一下:把内聚性和引起一个模块或者类改变的作用力联系起来。

一个类应该只有一个发生变化的原因。若Game类有2个不同的职责,一个是记录当前轮,另一个式计算分数,最后要把这两个职责分离到两个类中。为何把这两个职责分在单独的类中呢?因为每个职责都是变化的一个轴线,当需求变化会反映为类的职责的变化。如果一个类承担了多于一个职责,那么引起它变化的原因就会有多个。

如果一个类承担的职责太多,就等于把这些职责耦合在一起了。一个职责的变化可能会削弱或抑制这个类完成其他职责的能力,这种耦合或导致脆弱的设计,当变化发生时,设计会遭受到预想不到的破坏。

定义职责:如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责,有时候我们很难注意到这点,我们习惯以组的形式去考虑职责。

public interface Modem{

public void Dial(String pno);

public void Handup();

public void Send(char c);

public char Recv();

}

接口包括了2个职责,第一个职责是连接管理,第二个职责是数据通信。

如果应用程序的变化方式总是导致这两个职责同时变化,那么就不要分离他们,分开他们就会有不必要的复杂性味道。仅当变化发生时,变化的轴线才有实际意义,如果没有征兆,那么应用SRP或者任何其他原则都是比明智的。

分离耦合的职责:经常会有一些和硬件或者操作系统的细节有关的原因,迫使我们把不愿意耦合在一起的东西欧和在一起了。然而,对于应用的其余部分来说,通过分离他们的接口我们已经解耦概念。

如果ModenImplementation implemet DataChannel,Conection。ModenImplementation看起来是一个混杂物,或者有缺陷的类,所有的依赖关系都是从它发出来的。谁都不需要依赖它,谁都不需要知道它的存在。因此,我们已经把丑陋的部分隐藏起来了。其丑陋性不会泄露出来,污染应用程序的其它部分。

持久化:如Emplyee:CalculatePay,Store,Emplyee类包括了业务规则和对于持久化的控制,这两个职责在大多数情况下绝不应该混合在一起。业务规则往往会频繁地变化,而持久化的方式却不会如此频繁的变化,并且变化的原因也不一样。把持久化系统和业务规则绑定在一起是自讨苦吃的做法。如果发现这种情况存在了,应该使用FACADE、dao或者proxy模式对设计进行重构,分离这两个原则。

SRP是所有原则中最简单的原则之一,也是最难正确运用的原则之一。

敏捷软件开发——开放封闭原则OCP

首先,让我们分析一下背景。什么是软件开发过程中最不稳定的因素?——答案是需求!需求在软件开发过程中时时刻刻都可能发生变化。那么,如何灵活应对变化是软件结构设计中最重要也是最困难的一个问题。好的设计带来了极大了灵活性,不好的设计则充斥着僵化的臭味。这样,也就引出了本文的主题:【开发封闭原则】。

下面,就来简单扼要的介绍一下什么是【开放封闭原则】。【开发封闭原则】包括两个特征:对于扩展是开放的;对于修改是封闭的。对于扩展开放,意味着模块的行为是可扩展的。对于修改封闭,就是说在扩展模块行为的同时不对任何既有代码或二进制代码(.jar)进行修改。当然,这里说的过于绝对。有时为了完成某些任务不得不改动既有代码。但是,我们的目标是尽量的遵守原则。

那如何才能做到对扩展开发,对修改封闭呢?关键在于抽象!那什么是抽象呢?

我个人的理解是:抽象是对事物本质的概念上的理解。面向对象的分析中应该以行为分析为主线。举一个例子说明:假如从北京到上海,我们可以坐飞机,可以坐火车,可以坐汽车,也可以骑自行车。那对于这个问题如何分析呢?这个问题的抽象又是什么呢?也许可以这样思考:飞机、火车、汽车和自行车在本质上都是交通工具。所以得到这样的分析结果:交通工具被抽象为父类,飞机、火车、汽车和自行车都是其特例化的实现,父类中定义一个抽象方法,可以将人从一个地方运送到另外一个地方,各个子类重新定义运送的方式。这个设计无可厚非!但是,注意了!如果哪天某个人心情不错,想从北京走到上海了。那他的交通工具又是什么呢?11路!如果把步行也算成交通工具那就太不符合实际了。所以,面向对象的分析角度,不应该是从事物物理方面的关联去分析,而应该是从事物的行为方面的管理区分析。对于这个问题,一个人从北京道上海,无论是怎么到达的,只不过是移动策略不同。

下面,就给出相应的示例代码来说明一下上述问题。

class Traveller {

private Car car = new Car();

public void travel(Address srcAddress,Address destAddress){

car.move(srcAddress,destAddress);

}

}

这是最开始直接使用Car的旅行者,如果想替换成AirPlane怎么办?修改代码,用new AirPlane()代替Car。面向对象的实践原则指出:面向接口编程,而不面向实现编程。当代码依赖于具体实现时,就缺失了灵活性,面对新的扩展(也就是新的实现),必须修改既有代码。

接着,给出设计灵活的代码:

class Traveller {

private TravelStrategy _strategy;

public void travel(Address srcAddress,Address destAddress){

_strategy.move(srcAddress,destAddress);

}

public void setTravelStrategy(TravelStrategy strategy){

_strategy = strategy;

相关文档
最新文档