从结构化到面向对象程序设计的模型转换∗
袁胜忠
山东大学威海分校现代教育技术部 威海264209
摘 要:随着软件系统内在复杂性的不断提高,面向对象技术已经取代结构化设计技术成为产业化软件开发的主流技术。本文剖析对象模型与结构化设计瀑布模型队程序设计风格的影响,探讨导致面向对象软件工程失败的主要原因,论证了成功实施面向对象软件工程的关键技术,帮助软件工程师完成从结构化设计实践向面向对象分析和设计实践的进化。关键词:对象模型 瀑布模型 迭代和增量式开发 面向对象软件工程
Model Changing From Structured Design Style to
Object-Oriented Programming
YUAN Shengzhong
Department of Modern Education Technology of Shandong University at Weihai, Weihai,
264209
Abstract: In the past several years, with enhance of inherent complex of various systems, the object-oriented technology have actually become the main stream of industrial software development. Compared with traditional structured design style and the waterfall model, in this paper, we strength the correct understand to object model and discuss the main reasons for the failure of object-oriented development in order to promote the software engineers evolution from structured design to object-oriented analysis and design.
Keywords: object model; waterfall model; iterative and incremental development; object-oriented software engineeringpascal语言面向对象吗
1 引 言
面向对象的技术可以分为:面向对象的程序设计语言,面向对象的数据库技术,面向对象的分析和设计方法。
对应用软件开发组而言,面向对象的分析和设计方法是一种新的方法,它比面向对象的程序设计语言和面向对象的数据库技术更加难以掌握。因为它与开发组熟悉的结构化设计方法是两种完全不同的设计风格,在建立系统时,结构化设计方法利用算法作为基本构件,而面向对象方法利用类和对象作为基本构件。二者要求开发组用不同的思考方法对待问题的分解,而且面向对象设计方法创造出来的软
件体系结构大大超出了
∗作者简介:袁胜忠:男,1965年出生,软件工程师,主要研究方向为应用软件开发,网络管理与优化。
结构化设计文化的领域。
在应用软件开发中,面向对象方法至今没有得到应有的使用。正如Rentsch曾经准确地预料到的[1],“我猜想面向对象的编程将出现在20世纪的80年代,就像结构化编程出现在20世纪的70年代一样。每一个人都会喜欢上它。每个制造商都会改进自己的产品以支持它。每个管理者都会在口头上承诺它。每个编程人员都会(以不同方式)实践它。但是没有一个人会知道它是什么”。遗憾的是,在我们的开发过程中,Rentsch的预测至今仍然是正确的。
现在多数程序员都仅在结构化设计原则方面受过正规或非正规的训练,并利用这些结构化设计技术开发和实施了无数有用的软件系统。他们即使认识到只使用算法分解可以应对的复杂性是有限的,必须转向面向对象的分解;他们即使想早日使用面向对象的技术,反复学习了C++或JA V A,但是,他们发现面向对象技术很难应用,面对问题领域的时候,设计一开始就不自觉地转换到结构化程序设计上了。这一切都是因为他们还没有真正掌握面向对象的分析与设计方法,没有深刻认识面向对象的分析和设计方法与结构化设计方法的根本区别。没有正确的方法指导,只学习面向对象的程序设计语言是
远不足以成功实施面向对象应用软件开发的。如果把C++和JA V A这样的语言作为传统的面向算法的语言来使用,就不仅不能利用它们所赋予的功能,而且结果比使用更早的语言如C或PASCAL 还差。如果给一个根本不懂电的木匠一把电钻,他有可能把电钻当成锤子来用并在砸弯无数个钉子后认为电钻不如锤子好用。
本文在第二部分分析如何全面理解面向对象分析的模型,在分析的开始阶段,模型提供了一种组织大量信息的机制,这些信息起初使分析者无从下手。此外,模型的规范化和系统化会暴露出系统种的不一致性和缺陷,从而指导后续的开发工作,所以,模型对于正确掌握面向对象的方法是很重要的。在第三部分,作者结合自己的实践经验总结了导致面向对象开发失败的主要原因,用反证法论述了成功实施面向对象软件开发的关键概念和技术,希望帮助那些熟悉结构化设计方法的同行避开这些陷阱,顺利进化到面向对象的分析与设计开发。第四部分是结论,阐述了什么情况下应该采用面向对象技术。
论述中经常用到的概念有[2]:
(1) 面向对象分析(object-oriented analysis,有时称作OOA)。OOA是一种分析方法,它以可在问题域的词汇表中到的类和对象的观点来审视需求,强调利用面向对象的观点建立真实世界的模型。
(2) 面向对象设计(object-oriented design,有时称作OOD)。OOD是一种设计方法,它包含面向对
象分解的过程,以及一种表示方法,用来描写设计中的系统的逻辑模型与物理模型和静态模型与动态模型。正是对面向对象分解的支持使得OOD与结构化设计大不一样:OOD使用类和对象抽象在逻辑上构建系统,而结构化设计使用的却是算法抽象。
上述两个概念的关系是:OOA的结果可以作为OOD开始的模型,接着利用面向对象编程实现。OOD的结果可以作为完整实现一个系统的蓝图。
(3) 面向对象的开发(object-oriented development)。面向对象的开发是一个迭代和增量式的开发过程。其宏观过程为[2]:
·建立核心需求(概念化)
·开发要求的行为的模式(分析)
·创立体系结构(设计)
·演化实现(演化)
·管理后续的演化(维护)
微观过程为[2]:
·识别一个给定的抽象层次上的类和对象
·识别类和对象的语义
·识别类和对象之间的关系
·规定这些类和对象之间的接口,然后说明这些类和对象的实现。
2 深刻理解面向对象分析的模型
面向对象的分析,其目的在于有效地描述与刻画问题领域的信息和行为。实现这样一种描述,必须以一种全局的观点来考虑系统中的各种联系,系统的完整性和一致性。同时,这种描述能够说明系统中各种操作的细节。
为达到面向对象分析的目的,面向对象的分析提供了有足够表达力的模型:逻辑模型(类结构、对象结构)和物理模型(模块体系结构、进程体系结构)。对于一个给定的项目,分析和设计的结果都是通过这些模型表示出来。
其中,类结构的静态语义用类图表示、动态语义用状态转换图表示;对象结构的静态语义用对象图表示、动态语义用交互图表示;模块体系结构的静态语义用模块图表示、动态语义用子系统图表示;进程体系结构用进程图表示。
由此可见。面向对象开发的表示法包括四个基本图:类图、对象图、模块图和进程图,以及两个补充图:状态转换图和交互图。
·类图用来显示类和它们的关系在系统的逻辑设计中的存在。类图代表系统的类结构视图。
·对象图用来显示在系统的逻辑设计中存在的对象和它们的关系。对象图通常用来表示场景。
·模块图用来显示在系统物理设计中分配给模块的类和对象。模块图代表系统的模块体系结构的视图。
·进程图用来显示在系统物理设计中分配给处理器的进程。进程图代表系统的进程体系结构的视图。
·状态转换图用来显示给定类的实例的状态空间,引起由一个状态向另一个状态转换的事件,以及由状态变化引起的动作。
·交互图用来跟踪与对象图同一个语境中的场景的执行。
在应用软件开发过程中,设计行为不是一种画图的行为,图只是被用来描绘一个设计。面向对象方法从以上多个视图来观察设计是很重要的。在面向对象的分析方法中,建立数据流图的作用,不如其它面向功能的方法明显。因为数据流图中并没有添加任何新的信息[5],但是,建立动态模型可以使系统分析者对系统设计进行精化,把相同或相似的处理操作进行调整,使系统结构更加完善。
注意,面向对象的系统分析提供了一种独特的方法,它反映了软件问题的本质所在。软件问题的本质在于数据处理,数据和处理是两件显然的事情,是我们进行软件设计要做的最基本的工作,在分析数据和信息的过程中分析其处理过程是我们本来应该这样做的。将数据和处理人为地分离,可能会人为地制造系统分析的障碍。面向对象的分析是一种以数据或信息为主线,数据和处理紧密结合的方法,这种方法是以建立对象模型为基础的。
3 导致面向对象开发失败的主要原因
3.1 原因之一 ——在面向对象开发过程之上叠加瀑布型思维
如果您的开发过程基本遵循(1)企图定义和稳定绝大部分的需求,然后签署开发协议;(2)基于需求,进行详细设计;(3)基于设计进行实现;(4)进行集成、系统测试和部署。这是一个线性的、串行的瀑布型生命周期的典型例子,而且是一个最优先的导致面
向对象开发完全失败的策略。
虽然我们接受了瀑布式模型教育,但是瀑布式开发模型没有得到任何统计意义上的证据支持。更加重要的是,当前的软件项目失败研究结论性地表明[3],瀑布模型是风险最高、极易失败、低生产率以及高缺陷率的软件构建方法。尽管它与20世纪60年代开发软件的随心所欲方式相比是相对合理的策略,
但几代师生不假思索地学习和照搬它已经导致了很多软件开发的失败。有些东西必须像建筑那样被建造,但是软件通常不属于这一类。瀑布模型导致软件失败的最具有说服力的是一个错误的假定,即可以在项目的第一个阶段中定义绝大部分的需求。Capers Jones等人的研究粉碎了这一神话,蔓延的需求(在项目开始时没有预见到)是软件开发中非常显著的事实,在普通项目中它大概占到25%,在大型项目中则占到50%。
瀑布模型竭力回避需求变化的现实,它假定需求和设计能够正确地被指明和冻结,这与项目的现实严重不符。软件开发在设计和实现之前无法固定需求有许多原因,但不管什么原因,高明的应对方法不是去“对抗变化”,竭力固定需求,而正相反,应该像Ken Beck 积极主张的那样“拥抱变化”,并把这当作软件过程的一个核心驱动力。
OOA和OOD使用迭代的、增量式的过程,并考虑它的不同阶段的目的、产品、活动和度量标准。开发的行进表现为一系列的迭代,迭代过程不断地对面向对象体系结构进行细化,并将以往的经验以及每次发布的结果用于下一个迭代阶段的分析和设计中。增量式的开发过程要经过一个分析、设计、演化的生命周期。以便不断精化战略决策和策略决策,最后发展成一个满足用户实际需求的(经常是未加说明的)、并兼顾简单性、可靠性和适应性的系统。
在一个迭代中,有一种类似微型瀑布的情况。首先挑选一小部分需求,相对全面地对其进行分析,用
几天的时间进行设计,然后迅速地对系统的这一部分开始实现、集成和进行实际的系统测试与压力测试。每次迭代的结束将产生一个可运行的部分系统,它能产生反馈,并引发未来迭代中对需求和设计的调整。随着时间流逝,这些反馈-适应周期揭示了一组合适的需求和一个健壮的、经过验证的设计与实现。这里,串行的瀑布方法在周的实践内得到了应用,当迭代长度增加到月或年,这种方式将不再有效。
所以,面向对象开发的迭代和增量式的生命周期不同于瀑布型生命周期,其过程既不是严格的自顶向下,也不是严格的自底向上,正如Druke所指出的:通过使用“反复综合设计”(round-trip gestalt design),可以最佳地构造出结构良好的复杂系统。一个面向对象开发的项目团队面临的最大挑战就是有意或无意地在迭代和增量式开发之上叠加瀑布模型。典型的错误有(1)在设计或实现之前就确定绝大部分的需求;(2)项目刚开始就期望获得可信的估算和详细的计划;(3)把迭代和增量式开发四个阶段(起始、细化、构建和移交)与瀑布模型四个阶段(需求、分析设计、实现和部署)直接等同起来;(4)迭代不是太长就是太短。
3.2 原因之二——把面向对象开发当作一个有许多步骤需要遵循的规范过程来运作
尽管我们希望面向对象的开发有规律可循,但是,“对象对于不同的人意味着不同的事物”[2],面向对象开发的实施过程充满了创新性,它可以被足够明确地定义,但不能像食谱一样被描述,谁也不能确
保有适用于任何组织的成熟的、可重复的开发过程。Grady Booch提出要有一个管理良好的迭代和增量式的生命周期,“管理良好”意味着开发过程是可控和可测量的,但又不至于严格到影响发挥创造性和创新性的程度。即成功的面向对象的项目是既不遵循失去控制的生命周期也不遵循极度严格的生命周期,相反,成功地构造出面向对象体系结构的过程是迭代和增量式的,是一个经济且有弹性的过程。
在面向对象开发的核心理念和最佳实践中,迭代式开发的地位是最突出的。对于正从瀑布式价值观和实践上开始转变的开发者而言,迭代式开发就像一场革命,它灵活地支持需求的变化并随之作适应性调整,不像瀑布模型那样具有表面上明显的稳定性和确定性——其实这是具有欺骗性的,只有通过测试,才能评估对事物真伪的预先假定,只有通过实现,才能知道完成一个任务到底需要多少工作量。因此,如果没有在对待软件思考的许多层面上经历痛苦的变革,通常就把握不了迭代式开发并真正采用它。
为了让迭代式开发发挥作用,客户必须参与其中。迭代式开发的精髓是根据反馈进行及时调整,而不是预先揣测。客户的积极参与能帮助开发人员从理解需要解决的问题开始,以一种演进的方式,将功能和易用性变得真实有效。
大张旗鼓地或强制性地要求所有的项目切换到面向对象开发上来是无用的。好的经验是,在一位有经验的教练指导下,通过一个小型的示范项目,尝试采用一批少量的、简单的面向对象开发方法,让项目组从实践中学习,逐渐增加实施内容,在完成第一个项目的基础上再启动第二个项目。
3.3 原因之三——忽视对象技术技能
面向对象技术项目失败或遭到严重挫折的一个普遍原因是缺乏真正地能以对象方式思考,熟练掌握对象设计、对象模式和面向对象编程的人员。拥有技艺精湛的面向对象开发人员是一个绝对优先的关键成功因素,而采用迭代和增量式开发或其它过程则相对次要。正如Kempf所说[4],“相比学习另外一门编程语言,学习面向对象的编程是一项更困难的任务。这可能是这样一种情况,在相同框架中涉及到的不是一种新的编程而是一种关于编程的新的思考方式”。
要培养拥有出对象技能的人员,并非指先有一个星期的JA V A技术课程,然后是一个星期的面向对象分析与设计课程,而是需要向软件工程师提供半年内大致八周的、有老师精心指导的培训,之后还需要一年左右的专家辅导巩固期。先在一些风险低的小项目使用面向对象的开发,允许开发组犯错误,然后让这些开发组成员去开发其它的项目并担当面向对象方法方面的导师。将构造良好的面向对象系统别的示例展示给开发人员和管理人员也是发展面向对象思想倾向的好方式之一。总之,对象技术开发技能绝非一般,成功的对象设计与编程需要受过良好训练的开发人员。如果回避那些真正懂得迭代式开发的顾问、让技能生疏的工程师勉强参加开发或不聘用或培养熟练的对象技术人才,就会确保项目失败。
明确软件开发归根到底是一项人为活动是很重要的。面向对象开发的人员之间是不可以互换的,任何
一个复杂系统的开发都需要一个作为核心的开发组的各位成员所具有的独特和各种各样的技能。与传统开发方式相比,面向对象开发过程需要对不同的技能有一个很细致的划分。Grady Booch认为,在面向对象的项目组中主要有项目构架师、子系统设计领导、应用工程师三类角。
项目构架师是构想家,负责演化和维护系统的体系结构。对于中小型系统来说,系统体系结构的设计通常由一个或两个具有独特洞察力的个人负责。但对于大型项目来说,系统体系结构的设计则由一个较大的项目组负责。项目构架师并不需要是最高级的开发人员,但他应具有丰富的建造类似系统的经验,凭直觉就能判断出哪种公用的体系结构模式与给定领域有关,以及什么样的性能问题可能出现在特定的体系结构变体中。项目构架师也不需要是最好的程序员,但他应精通面向对象开发的表示法和过程,因为他必须根据类
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论