CSDN博客

img isaxu

第七篇:从程序员到系统分析员 之二

发表于2001/8/2 15:20:00  597人阅读

 

Linuxaid.com.cn 01-07-18 16:08 453p axing


四个阶段

    这里我不想举一大堆的数字和实例来描述软件危机和论证软件工程的重要性,这方面的资料有很多,如果一一列举的话,会被怀疑别有用心(^_^)。在上一篇中,作者告诉即使我们建立的是一所狗舍,不必需要那么详尽的设计,但仍然需要一些草图,以做到心中有数。事实上,建造狗舍和写一个小的软件没有很大的区别。虽然你认为你的能力可以很轻松的完成小型的软件系统,根本不需要任何的计划。好!我来问问你,你在写程序代码的时候,有没有过漏这漏那,程序快接近完成的时候却发现少了一个很重要的模块;有没有过在书写了大量的代码之后觉得自己写出来的东西不堪入目,恨不得重头开始;有没有过写程序花了两天的时间,但是Debug却花了一个星期的时间;有没有过听到软件的使用者说要改需求,你就恨不得狠狠揍他一顿。如果都没有,那么只有两种可能:你是个超级天才,所有人类能够想到的美好品质你都具有,另一种可能:你根本没有开发过软件。

    即便是个人开发的软件,软件工程科学中也有相应的方法来指导软件的开发过程,这种方法叫做PSP(个人软件开发过程),与此相对的,还有TSP(小组软件开发过程)。这些被事实证明行之有效的方法包括了一整套的规范,帮助你开发你的软件,不让你的程序变得无法控制。可以说,对于任何一个软件系统来说,只要你花一些时间去设计,即便你的设计仅仅只是在草稿纸上随便的涂抹,在软件开发完成后,你就会惊喜的发现,你在软件开发早期的小小投入,已经为你带来了额外的好处。

    路标和RUP

    在阶段0中,我想最重要的思想就是就是“路标”的概念了,和这个概念相类似的概念还有“周期”和“里程碑”的概念,这些概念在Rational公司的RUP(Rational Unified Process 软件统一过程)中有详细的论述。不论这些概念叫做什么,他们体现出来的是一种迭代开发的思想。面对当今的复杂的软件系统,使用连续的开发方法:如首先定义整个问题,设计完整的解决方案,编制软件并最终测试产品,是不可能的。需要一种能够通过一系列细化,若干个渐进的反复过程而生成有效解决方案的迭代方法。

    Rational Unified Process支持专注于处理生命周期中每个阶段中最高风险的迭代开发方法,极大地减少了项目的风险性。迭代方法通过可验证的方法来帮助减少风险--经常性的,可执行版本使最终用户不断的介入和反馈。因为每个迭代过程以可执行版本告终,开发队伍停留在产生结果上,频繁的
状态检查帮助确保项目能按时进行。迭代化方法同样使得需求、特色、日程上战略性的变化更为容易。(出自《Rational Unified Process白皮书》)

    上面这段好像很复杂,但是他所要说明的思想却是很简单的,就拿搭建狗舍来说,你的第一个“路标”可能是要搭一个框架,这个框架是由几根结实的木头组成,等到框架完成之后,你会把你的小白叫来,让他试一下,糟糕的是,这个框架对于小白来说小了一些,这时候你嘘了一口气,因为你原来是打算把整个狗舍搭好以后再叫小白来试一下的,如果你那样做的话,你剩下的木头可能就不够再盖一间狗舍了。好吧,既然有了些问题,我们就把框架调整一下,可能这个过程也花了你一些木头,不过所幸木头还够。在修整完毕后,你觉得第一步的计划虽然有些挫折,不过仍可以算是成功的,接下来你就要建立第二个“路标”了:第二个的“路标”是为狗舍钉上墙板和做出一个底座,你可能花了一些时间来思考以及和你的小白商量是否要在墙壁上开一个窗户和给底座加上轮子,在决定之后,你很快的达成了第二个“路标”。而且在经过了小白的测试后,你发现完全没有问题,你自己都觉得有些佩服自己了,很快的,你又完成刷油漆等“路标”。整个过程进展的非常顺利,而你在做狗舍方面很有天赋的名声也在你的街坊四邻间不胫而走。

    很简单是吧,其实本来就是简单的,软件工程的目的就是要把复杂的软件开发过程条理化,简单化。记住,在你使用迭代开发方法的时候,它在每个周期后的产品是一份可执行代码,是一份可以让你的用户品头论足的东西。而这份可执行代码不仅包括了程序本身,可能还有其他的产成品,例如:文档等。

    问题和场景

    在阶段1中,非常重要的一点是问题描述,在多数情况下,问题描述来自于你的软件的使用者,就是用户。用户的需求决定了问题描述,糟糕的是,用户多半不懂计算机,对他们来说,他们只能够用日常的语言来表达自己的需要。而你的任务就是要把他们的语言翻译成计算机语言,不过并不是指象C那样的高级语言,而是便于你构造系统的需求描述语言。这同样很简单:你只需要问自己几个问题就可以:在什么场合?有什么条件?做些什么事?回答好这三个问题,你就完成了一个完整的问题描述了。

    举一个简单的例子:一个银行的信贷系统有这样的问题描述:

    “若顾客采取信用贷款方式,销售员就请求信用部门的审核人员查核顾客的信用,此时审核人员会向销售员取得顾客信用编号和销货总金额。”

    在某种条件下应该做什么事情,这就是这个问题描述的表现形式,很简单是吧。

    实际上,这里可以引申出两个概念:场景(context)和问题(problem),场景指的是一种特定的情况,会导致某种问题的发生;而问题是在某个场景之中,但它也有可能产生出新的场景。

    过程和对象

    有必要说明一下以前基于过程的软件开发和目前基于对象的软件开发的不同。在没有OO的年代里,DFD(Data Flow Diagram 数据流程图)是一份软件设计中的非常重要的文档,注意力的关键也是集中在数据如何在各个系统之间传递。可是在现在的OO概念中,数据大有为消息(message)所替代的趋势。比如你到麦当劳快餐店,要花10块钱买一份汉堡。在DFD的时代,就是这样表示的:

DFD图

    如果你用消息表示法来表示话,就是另一种方式:
MFD图

    怎么样,你觉得那一种方式更自然呢。(如果你敢回答第一种的话我就...)。再比如上一段话中关于问题描述的例子,如果用传统的数据描述的方法的话,就会是这样子的:

    “若采取信用贷款方式,销售员就将顾客信用编号及总金额交给信用部门的信用审核人员。”

    请比较其中的两句话:

    “若采取信用贷款方式,销售员就将顾客信用编号及总金额交给信用部门的信用审核人员。”

    “若顾客采取信用贷款方式,销售员就请求信用部门的审核人员查核顾客的信用,此时审核人员会向销售员取得顾客信用编号和销货总金额。”

    了解其中的不同之处了吗,用自然的语言去描述你的问题,这是写出好的软件的第一步。

    系统分析员的语言

    场景描述是一个很不错的方法,可是随着你对系统的分析的深入,参与开发的人员的增加,你渐渐的感觉这种方法不够用了。原因有很多:文字的描述不够直观,不可能到达一种很细致的程度。这时候就需要一种能够描述问题、描述解决方案、起沟通作用的语言。这就是UML。

    UML(Unified Modeling Language 统一建模语言)是由Rational公司发明,目前由OMG(标准化对象管理机构)维护。作为一种建模语言,UML的定义包括UML语义和UML表示法两个部分:

    UML语义 

    描述基于UML的精确元模型定义。元模型为UML的所有元素在语法和语义上提供了简单、一致、通用的定义性说明,使开发者能在语义上取得一致,消除了因人而异的最佳表达方法所造成的影响。此外UML还支持对元模型的扩展定义。

    UML表示法 

    定义UML符号的表示法,为开发者或开发工具使用这些图形符号和文本语法为系统建模提供了标准。这些图形符号和文字所表达的是应用级的模型,在语义上它是UML元模型的实例。标准建模语言UML的重要内容可以由下列五类图(共9种图形)来定义:用例图、静态图、行为图、交互图、实现图。

    从应用的角度看,当采用面向对象技术设计系统时,首先是描述需求;其次根据需求建立系统的静态模型,以构造系统的结构;第三步是描述系统的行为。其中在第一步与第二步中所建立的模型都是静态的,包括用例图、类图(包含包)、对象图、组件图和配置图等五个图形,是标准建模语言UML的静态建模机制。其中第三步中所建立的模型或者可以执行,或者表示执行时的时序状态或交互关系。它包括状态图、活动图、顺序图和合作图等四个图形,是标准建模语言UML的动态建模机制。因此,标准建模语言UML的主要内容也可以归纳为静态建模机制和动态建模机制两大类。

    这样说,你可能还是不了解UML到底是什么,不过UML并不是我们讨论的重点,你只需要知道UML是一种建模语言,他的目的就是在开发团队之间提供一种通用的、简单的沟通机制,并且UML是面相对象的。

    上面所说的这些就是阶段2的重点所在。使用UML语言对阶段1中提出的问题描述进行深化,从各方各面看待问题:顺序、流程、数据、状态、接口等。最终你得到的是一套完整的文档,做为详细的程序设计的参考和标准。

    不要累坏自己

    上面说了这么多在编程之前要做的工作,但是要注意的是,不是所有的开发工作都必须做这么多的工作的。对于你来说,抓住最重要的内容,不要涉及到太多的细节。对你写出来问题描述,必须要仔细的分析,而这里的分析呢,并不是要你用程序来实现你的问题描述,而是你必须从问题描述中分析出对象(object)、事件(event)和消息(message)。例如上面所提到的例子:

    “若采取信用贷款方式,销售员就将顾客信用编号及总金额交给信用部门的信用审核人员。”

    你可能看到这句话以后就会在想做一个审核信用的函数,参数部分有信用编号和总金额,然后开始设计程序的细节。如果你是这样干的话,这说明你还没有真正了解OO的思想,你的开发方式仍然停留在以前基于过程的开发方式中。那么面相对象的分析是怎样进行的呢。我们还是来看这段话,撇开你的程序,你的语言,你从这句话中获得了什么信息?是的,你知道说这个企业中有销售员、有信用审核人员;要求审核顾客信用是他们的工作之一;顾客的信用编号和总金额是审核顾客信用的时候的重要信息。这是任何一个普通的人看到这段话后的感觉,这就是OO的分析(在OO中这种的分析方法称为OOAD)。其实是很简单的,和你采用什么样的程序一点关系都没有。

    软件重用(Reuse)是软件工程中最重要的思想之一,只有软件重用,才能降低软件成本,提高软件的质量。你在对一个软件进行分析的时候,找出可以重用的对象,有助于你开发高效的软件系统。正如前面所说的,你不必把软件分析的过分细致,你只需从中找出关键性的、能够重用的对象就足够了。剩下的事情,就是对这些对象分配属性和方法,并充分的使用这些对象就好了。

    还是那个例子:我们已经从中看到了一些对象:销售员、信用审核人员。但是他们在系统中不具备重用性,至少是重用性不强。信用部门这个对象也存在这个问题。所以不能够把他们作为底层的对象,我们用一个术语Entity Objects 来称呼底层对象。那什么是软件系统中的Entity Objects呢?毛主席教导我们要透过现象看本质。上面的描述中有很多隐含的信息:

    顾客请求信用贷款:这里就包括两个Entity Objects:顾客、信用贷款。
    销售员、信用审核人员都是员工,所以员工也是一个Entity Objects。

    观察一个Entity Objects,你会发现,Entity Objects已经是最小的单位,是使用软件的用户(这里是银行)最小的单位。当然不但是这个软件有Entity Objects,比如我们最常用的Word,我们可以想象一下它的Entity Objects有什么,可能是一种叫做图元的Entity Objects,一个图元包括了文字、图象以及其他的对象。

    用OO的方法分析你的软件,从设计到实现都是非常的自然,可能你学习面向对象时是从C++开始的,被其中的虚函数、多态性、多基类继承搞得一头雾水。但是实际上OO的方法要比以前的方法简单的多,不相信?试一试,你就知道了。

    校订、校订再校订

    第3个阶段称为校订,这个称呼真是太贴切了,既不是测试,也不是返工。任何事物从诞生起都必须经历不断的改进才有可能成熟。(呵呵,说出这么有哲理的话,我都很佩服自己啊。)软件同样不例外。事实上,在阶段0中,我们就讨论了“路标”的概念,当你的第一个路标达成之后,剩下的应该都是属于校订的事了。通过和用户的交互,确定新的“路标”,不断的改进系统功能,优化系统结构,修正系统Bug。

    正如作者所说的那样,真正OO的软件是经得起修改的,由于采用了多层的结构以及面向对象的思想,以前软件的致命伤(修改)在新的开发方法面前不会是个大问题。(注意,这并不是说你可以无规划构建你的软件)

    由于以前的系统大多会将GUI、事务处理、数据存储都做在一起,当你需要修改一个地方的时候,你就会发现问题的严重性:一个小小的需求变动都意味着你的系统将面临伤筋动骨般的修改。在OO的时代里,所有的对象的访问都是通过接口(Interface)进行的,对象中方法的改变并不会接口产生影响,也就是说,调用该接口的模块不用做任何的修改。另外,如果你打算把你的系统的界面从C/S方式向B/S方式改变,同样不会有问题,你可以很容易的把GUI部分从原有的系统中剥离出来。软件的修改对你来说不再是一个恶梦。
0 0

相关博文

我的热门文章

img
取 消
img