`
gdpglc
  • 浏览: 88004 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

需求、需求分析、设计 思想

阅读更多

需求、需求分析和设计的概念,对我来说很抽象。在我做了几次相关的工作已后,它们在我的头脑中才逐渐清晰起来。我曾试图从别人的书中,了解它们的真帝,可是大家众说分云,和实际工作都挨不上。通常书里会说:“需求是做什么,设计是怎么做”。我觉得这两句话,是金玉良言,可是对于一个初学者来说,太难理解了。什么才叫做什么,用户想到的东西,可以说是做什么;一个方法里要写的功能也可以说成是做什么,这个尺度从“做什么”三个字里是看不出来的。还有一种说法:“需求分析是软件的问题空间(问题域),设计则是解空间(求解域)”,这个好象更不好理解了。看了这样的文字,除了晕还有什么呢?另有一些书里,则写了一堆做需求分析的方法,比如:用什么工具了,画什么图了,竟解释一些需求、设计相关的方法,使人看了知其然,而不知其所以然,最终还是不知该怎么做。更有甚者,把需求相关的工作的难度无限夸大,动则什么“需要系统分析员、用户、领域专家共同怎么怎么。。。,怎样怎样才能得到精确的模型”,而提供的则是一些支离破碎的建模方法,最终导致的就是需求分析、设计神秘化。

需求、设计的过程是一个可以明确说明和被理解的过程。会做和不会做的差别,不在于有什么魔法,只是一些可见的知识和实践经验。

这里要说明一点,本文所提的方法者是面象对象的方法。

需求、设计有许多的方法比如:booch oose omt coad&yourdon up xp等,方法不同,所使用的概念、侧重点,也不同。不过,它们即然是在做同一件事,就执必有相同的实质。比如:任何一个方法,都得考虑,在什么时候设计界面,和怎么设计页面。因此,只要搞懂了一种比较好的方法,其它的应该是可以理解的。

这里介绍一下目前我所使用的方法,它很简单但很实用,是我一直在实践中所使用的。

1.什么是需求

需求简单的说就是“做什么”而不是“怎么做”。但这种简单的描述并不足以限定需求的界限。

比如:

用户需要的功能是做什么---------怎么实现功能则是怎么做

一个函数的功能是做什么---------怎么实现函数则是怎么做

写一个for循环是做什么 -----------怎么敲键盘是怎么做

左边的这三项,显然在做软件时,是处于不同阶段的。因此说“需求”二个字是有上下文的。通常,我们说的需求是指用户的需求即“用户想要系统做什么”。 当然“需求”这两个字也会在其它的语境中出现,比如:你要你的下属为你做一个界面,你的下属会问你:“把界面需求给我”。这里的“需求”,就是特指“要做一个什么样的界面”。

按照上述关点,在软件中是处处有需求的,但是我们关注的是用户的需求。它是软件产生的根源,是贯穿软件的主线。

由用户需求,可以导出软件的需求,它描述了软件从用户的角度的确切样子。软件的需求有一个易忽略的意思,就是软件的性能、可靠性等、统称为非功能需求。

2. 需求怎样获得取

需求来源于用户,但是由于用户并不懂得如何用记算机解决问题,也有可能,用户本身并不很明确所面对的问题,因此需要和分析员共同明确用户的原始需求。这一步可以称为“需求调研”。

进行需求调研需懂得一点建模的方法。我比较喜欢用例图。在和用户交流时一定要用简单易懂的工具。

3 .需求分析

当获得了原始需求后,需要进行的工作就是“需求分析”。需求分析的方法很多,不同的方法使用不同的步骤,测重点也不同,实质上都是为了驱动设计和软件的开发。我所使用的方法自成一格(不是我发明的),简单实用,没有用看不懂的话来指导分析和设计。

方法的核心思想是:做软件是为了用户,用户需求是软件的根本,软件的一切都是由用户需求推导面来,是贯穿于分析和设计的主线,需求分析和设计的划分要适用于交流和团队开发,不拘泥于某种建模方法,但提出主要的三种模型和建模顺序来完成需求和设计的推演。

需求分析的结果是需求分析文档,文档的目的是要澄清用户的原始需求,明确用户需求模糊的部分,理解问题域,设计解决方案。这时通常要用到用例图进行分析。通过用例可以捕获软件的功能需求。分析时还要确定对软件的约束。当切底理解了问题域以后,就要设计解决方案。解决方案是指明软件的功能需求、非功能需求、界面。

为了理解问题域,通常需要明确问题域中的概念,对现实世界进行分类,挖掘新的概念。

需求分析最后的效果是,当拿到这样的一份文档以后,就可以了解到软件开发出来以后的全貌以及实现上存在的约束条件。同时可以包括对设计的一些建义,比如使用什么开源组件,设计的核心思想等。

这里的需求分析,建议的就只有一个用例图,用来捕获用户需求。其它的建模原素只要是有利于理解问题域的就可以使用。

这和一些经典的OOA 方法不同,它们强调类图是需求分析的核心产物。但我觉得,无明确目的找类,是不能证明所找到的类是有用的。就是说,找类的动作是没有用户需求驱动的,这时找到的类是不能证明对用户需求是有用的。因此说,这里描述的方法的核心是用户的需求,而不是领域模型。有些OOA方法,把界需设计的动作方到了OOD的过程中。我觉得,这不太合适,因为界面是用户最真接体验的软件部分,应该先确定下来,并与用户讨论。有利于用户对软件系统的理解,并可以提出意见。

需求分析,需要经过认真的评审,需要用户的参与。

由于认为用户是最重要的,因此怎样实现软件或者说怎样设计软件,则处于次要的地位。 但不要误会我的意思,我的意思不是设计不重要,只是说从用户的体验来讲,设计的好坏不起决定作用。

4. 设计

设计的最终目的是找到一组类,并明确类的职责,通过类的协作完成软件需求分析时所确定的需求。最后应形成设计文档,程序员根据设计文档可以进行软件的编写。

一、画顺序图

通过需求分析阶段确定的用例可以确定系统的主要的外部事件。设计的第一步是用顺序图描述最主要的外部事件所激发的类协作。这里有个问题,类从何处而来?类为需要面来,就是说为了实现某一个外部事件,需要某个类的出现,则在顺序图中将它画出来。这里隐含了一个意思,现实世界中的对象是画顺序图时提取对象的一个源泉。另外一些模式也为应用什么类来实现外部事件提供了指南,比如:通常使用的控制器模式。

这里注意: 外部事件是由用户需求而来,顺序图是由外部事件而来,所以找到的类必然是为用户需求所服务的。

第一个顺序图应该确定软件的主要公共类。主要公共类是软件中的必然成份,负责一个独立的功能。

接下来继续画顺序图描述其它的外部事件在主要公共类间的协作关系。当所有的外部事件的顺序图都画完了以后,则所需的主要的类和类的公共方法都可以确定下来了。

有些公共类内部的协作过程如果还不明确则应针对这个类的公共方法再画出顺序图,以发现更细致的协作过程和和更小的类。

画顺序图的过程是找到了类,并为类分配职责的过程。最初通过外部事件,找到主要的公共类,并为它们分配职责,然后为了实现公共类的职责,继续发现一些细小的类,最终细化到可实现的级别。

注意:设计的指导思想是,越简单越好。

二、画类图

通过上一步,找到了系统内需要的类对象。现在可以用类图将这些类画出来,根据顺序图、类的职责、现实世界可以确定类之间的关系。通过顺序图可以确定类的公有方法,根据公有方法和类的职责,可以确定类所需要的属性。

三、用文字详细说明每一个类的职责、功能、属性、方法,以备程序员根据设计文档实现软件。

上面叙述了软件设计的一般过程,但光知到这些,并不足以做出优秀的设计。还需要理解面向对象方法的本质原理,学习设计模式,架构模式,重构等内容,还需要实践,实践应该是最重要的。如果是初学,我想先学设计模式好点。

我觉得设计没有对错之分,只有好坏之别。好的设计的特点是:第一、设计要简单易懂,易于修改、扩充,它是第一位的,第二是有适当的灵活性。坏的设计的特点是:设计复杂、不易理解、不易修改和扩充。

现在介绍一下面象对象方法的本质原理。首先说对象,对象是面向对象方法的核心原素。对象可以表示现实世界中的一切。对象本质上就是:数据+方法,这种组合在软件中到底有什么好处呢?软件所解决的问题,实质上都是客观事界中的问题。一个问题,必然由一些事物、概念和这些事物及概念的运动所组成。如果要在计算机中解决先实世界中的问题,必然需要在软件中表示出现实世界中的事物和概念,才能进行运算。比如:一个下定单的系统中不可能不包括对定单的表示和操作。可以说,软件世界,是现实世界的一个映射,类恰好是完成这个映射的恰当工具。因此可以说,相同需求下,不同人做的不同设计本质上是等效的。

用面向对象方法写的软件,比较好理解。因为它比较接近现实世界。

用面向对象方法编写的软件是比较稳定的。因它软件中包含了现实世界的映射,而先实事界,通常是稳定的,变化通常是在局部的。因此对应的软件也只需要局部的调整。

软件世界中的对象是现实世界的映射但又不完全相同。原因是为了实现需求,必须为现实世界中的事物或概念添加行为。比如:一个定单对象,它很可能包含一个amountTo操作来合计定单总额,现实世界中的定单是没有这个能力的。那为什么,不把amountTo方法分配给其它的类,进行总额的计算呢,这样是不是就符合现实世界了呢?这个问题,不能单纯从符合现实世界来考虑。前面说过,软件设计简单易懂,是根本。这样作明显会引入一个新类,当用到定单的地方,就有可能需要进行amoutTo计算,则在这个地方又必须使用那个引入的类,结果是明显增加了软件的复杂度。为定单对象增加amoutTo操作,对于它对先实世界的模拟是无害的,却可以简化软件设计,为什么不这样做呢?因此,如果以后要增加对定单的操作也应该加到定单对象中(对应这个意思有一个模式叫做“信息专家”可以参考《uml与模式应用》一书)

面向对象中的继承基本上是为了实现复用,但多态是借着继承来实现的,我觉得多态才是继承的真正好处。它使得一些精巧的设计模式成为可能,可以增加软件的灵活动性。

面向对象还有封装的能力,这个不必多说了。

先在说说面向对象的坏处:因为我没有用面向过程的方法做过大型软件,所以体会不多。但从我主观觉得,面象对象的方法,要比面向过程的方法,难以掌握,要学习的知识比较多还要精过大量的实践才能成为高手。

这里在说一个问题,是不是用面向对象语言写程序就一定要使用对象的诸多好处呢?我想这个不一定,更确切的说是有时根本不应该用。当使用对象反而使设计复杂时就不要用对象。这个情况可能在MS系统中比较容最出现,因它在MS中的操作大都是对DB中记录的增删改,这时每个方法要做的通常是把一个SQL发到DB就行了,这时直接在一个方法中操作数据实现计算过程就很好,用不着对象的诸多好处。当然还是会有一个类来包容这些方法的,但这个类只是方法的载体。(这个是《企业架构模式》中一个叫做“事务角本”的模式)。这种情况可以说,在方法的功能中,就是没有用到对象的。

因此说,设计不要拘泥于某个规则(因为我还不知道,什么情况下都可用的规则)。

软件设计中的分类和统一。我发现在软件设计时经常要对事物进行分类,为什么呢?原因是当软件设计中要处理的事物很多时,是很难针对每个事物都做一个处理的。因此只有把事物分成几大类,然后就只需对每一类进行一次处理就行了。在一类中的事物必然有其相同的特征,但它们又是不同的事物,那在软件中怎么表示呢?使用的就是继承和多态。这是一个统一的过程,将一类的事物的共同特性统一在基类里。对一类事物的处理就统一成为对基本的处理了。比如说(这个是我假想的,现实的情况我没做过):一个系统有三种定单和三种入库单,则明显定单和入库单的二大类事物,而每类中又有三种具体的事物。这个就比较适合用我上述说的书法来实现。就是说,为定单创建一个基类,对出库单创建一个基本类,则对定单的处理和对出库单的处理就只需对它们各自的基类进行了。

ok上述的内容可以统称为面向对象的实质性内容。设计模式就不在这里介绍了,关于它的论述在网上太多了,但还是建义看经典著作。比如Gof等的《设计模式》。

最后说一点,上述方法并没有对软件的架构级别的东西进行刻画。原因是这个方法目前是被用在迭代开发过程中的,每次迭代为软件加入一定的需求,这时软件的架构已经确定,因此本方法的设计过程主要是对象设计过程,可能跨越现有的几个子系统。

大型系统没有系统设计过程是不行的。这个过程应该在软件的第一次迭代中进行,这时的需求是对软件全局尺度上的重要功能的分析,对需求要进行优先级的划分,只对高优先级的需求进行详细分析,设计则包含系统设计和对象设计。系统设计主要是根据需求确定软件的子系统,对象设计则只真对当前最重要的需求明确的一个或几个子系统进行,其它子系统可以暂时留一下个占位的类就行了,具体的实现则放到其它的迭代进行。这个过程,暂时我还没有时间详细整理,暂时不在这里详述了。

基本上我已把我的思想都介绍完了。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics