技术开发 频道

要勇于面对需求变更

  从软件分析和设计着手

  前面说了面对需求变更的几种策略,那么从软件系统分析和设计的角度来看,通过采用合理的分析设计方法,进行可扩展性设计可以有效地降低需求变更引起的风险和维护代价。

  采用OO 技术

  采用OO 技术可以建立易于改变和加强可重用性的软件系统。

  对于OO 技术,我想现在已经不是什么陌生的概念:

  1 封装(Encapsulation )可以把问题影响的范围缩小,外部的变化要求对系统的影响可
  以限定到某个类层次或某些类层次中,从而改变系统的一部分相对简单;
  2 继承(Inheritance )可以使改变基于原有技术基础,很大程度上减少重复开发工作;
  3 多态(Polymorphism )的应用可以使开发和设计人员在相对统一的接口下更改系统的实现细节,从而改变系统的行为;
  4 而且由于对OO 的类体系结构业界有非常清楚明晰的描述方式,就是目前规范的描述语言-UML ,非常易于被开发组的理解并达成共识,促进开发组成员之间的合作以及加强软件开发工作的可延续性;

  可见本身即是一种增强软件可维护性、健壮性以及保持设计稳定性的一种分析和设计方法,本身可以在一定程度上快速对需求变更进行反应,并可相对减少需求变更需要的成本。(OO 的意义在于分析和设计软件系统的思考方式,以及建立对象库以后的软件重用将给软件系统的开发带来质的改变,但是在建立OO 开发体系之前的过程,一定会是一段荆棘遍布的路,需要付出加倍的努力以及达成思想的转变。这里还有一个误区需要澄清的是很多人以为用了C++,PB ,VB ,DELPHI 就是面向对象的开发了,其实只是用了一些面向对象的工具,骨子里仍然是结构化的分析和设计方法,套上一层OOP 的外壳而已。)

  可扩展性设计(Extensible-Design )

  其次,从我们可以控制的软件设计来说,怎样进行合适的设计才能最大程度减少需求变更带来的代价?

  也许有人说,我的设计极为灵活,我已经预计了客户可能提出的要求,并设计几种应对的方式,到时候客户提出来,呵呵,我已经解决了。这样的想法不错,至少比僵硬的设计强,但是谁可以保证设计者可以预知以后的需求变化?而同时为了达到这种灵活(功能较多/多能?)的设计,设计将变得复杂,而且可能那些多余的设计从来不会被用到?复杂的设计将增加实现的难度和提高成本,并有可能带来潜在的Bug ,使得系统难以维护。

  设计的思想应该有一些小小的转变,那就是,设计确实要灵活,但是要体现在可扩展性上面,也就是说,设计可以简单,但是一定要易于转变,需要给出便于改变的接口,这一点很重要。

  例如,现在有一个类叫做TCPConnection ,来代表计算机网络通信中典型的TCP 连接,对于这个连接而言,它可能处于以下几种状态:Established (连接已建立),Listening (正在侦听),Closed (连接关闭)。一个连接对象需要从其他的对象接受请求,至于它的反应则决定于连接对象所处的状态,对于(打开连接的请求),如果是在连接关闭状态,则进行Open (),处于其他状态则不做反应;同样,如果在连接建立和侦听状态,可以进行Close (),在连接建立状态可以进行Acknowledge (),即接收数据。

  对于这样的状况,最不可取的设计应该是用一系列的Switch 语句(甚至If/else 语句)进行Hard 设计,对于以后每一次需求改变,都需要改变源代码,接踵而来的系统一致性、文档更新等工作将使开发人员不可避免地陷入一场灾难,这样的后果将导致原来就不合理的设计变得更加支离破碎,系统维护的代价将越来越大;就算没有需求变更发生,这些设计的可重用性也会极差。稍好一些的设计是预先估计并设置TCPConnection 类所有可能的状态,并预先加入设计,这种需要付出更多的设计、开发、维护的代价,而且也很难达到完美的效果,所以不多说了。

  下面介绍一种经典的设计思路,这种设计可以充分体现“为(系统)将来改变预留接口”的可扩展性(Extensible-Design )思想,并且很好的实现了这一思想。在这里,我们引入一个抽象类TCPState 来代表TCPConnection 类的状态,给出具体各种状态的通用操作接口,并派生出不同的子类(实现具体的操作)

  去实现TCPConnection 类的不同状态,例如派生出TCPEstablished 类来实现TCPConnection 类的连接建立状态。结构图示如下:

        


  只需要在TCPConnection 类中包含一个TCPState 的状态引用,并在TCPConnection 的状态改变时更新为当前的状态引用,例如在连接关闭时进行Open (),状态引用就应该从TCPClosed 变成TCPEstablished ,这样就实现了原来的要求。

  但这个设计思路的意义远不止于此。我们可以看到,抽象类TCPState 已经为TCPConnection 类将来可能的状态留出接口,只需要不断派生具体的不同状态子类就可以实现将来的状态变更,并且无须影响原有的设计,也无须加入多余的代码来实现现在还不需要的功能,所以这是一个优美的、可扩展的设计思路,非常清晰,易于维护,相信可以给我们在做软件设计时带来一些启发。

  可见,在面对需求变更时,除了客观上可以通过人员培训、代价分析等管理方式进行有效的需求管理外,从分析和设计的角度可以通过采用合理的分析和设计方法,还有改变我们设计的意识,可以做到对需求变更的灵活应对,至少可以在一定程度上降低维护代价和提高用户满意度。

  软件需求的管理和控制是非常专业的学问,作者在这里结合自己的实践提出一些粗浅的认识,只是想起到一个抛砖引玉的作用,希望大家可以一起来面对和想办法解决我们在系统开发过程中的实际问题,我想那样才是我真正想达到的目的。

0
相关文章