【软件工程的框架】
软件工程(SoftWare Engineering)的框架可概括为:目标、过程和原则。
(1)软件工程目标:生产具有正确性、可用性以及开销合宜的产品。正确性指软件产品达到预期功能的程度。可用性指软件基本结构、实现及文档为用户可 用的程度。开销合宜是指软件开发、运行的整个开销满足用户要求的程度。这些目标的实现不论在理论上还是在实践中均存在很多待解决的问题,它们形成了对过 程、过程模型及工程方法选取的约束。
(2)软件工程过程:生产一个最终能满足需求且达到工程目标的软件产品所需要的步骤。软件工程过程主要包括开发过程、运作过程、维护过程。它们覆盖 了需求、设计、实现、确认以及维护等活动。需求活动包括问题分析和需求分析。问题分析获取需求定义,又称软件需求规约。需求分析生成功能规约。设计活动一 般包括概要设计和详细设计。概要设计建立整个软件系统结构,包括子系统、模块以及相关层次的说明、每一模块的接口定义。详细设计产生程序员可用的模块说 明,包括每一模块中数据结构说明及加工描述。实现活动把设计结果转换为可执行的程序代码。确认活动贯穿于整个开发过程,实现完成后的确认,保证最终产品满 足用户的要求。维护活动包括使用过程中的扩充、修改与完善。伴随以上过程,还有管理过程、支持过程、培训过程等。
(3)软件工程的原则是指围绕工程设计、工程支持以及工程管理在软件开发过程中必须遵循的原则。
—————————————————————————————————————————————————-
【引子】想学习一下软件工程,看到林锐的《软件工程思想》页数比较少真合我意(哈哈,我喜欢把一本厚书分成 几本看)。言归正传。
【第一章】软件工程的基本概念
1.软件工程的目标与模型
软件工程的目标—-提供软件的质量与生产率,最终实现软件的工业化生产.好的软件工程方法可以同时提高质量与生产率.
影响软件质量的因素—-正确性,性能、可靠性、容错性、易用性、灵活性、可扩充性、可理解性、可维护性等
软件工程的主要环节有—-人员管理、项目管理、可行性与需求分析、系统设计、程序设计、测试、维护等
常用的软件工程模型—-线性模型,渐增式模型,螺旋模型,快速原型模型,形式化描述模型等
做项目计划时切忌“冒进”,不要指望在项目陷入困境后靠增加人手来解救。软件的高质量主要是设计出来的,不是“管”出来的,更不能依赖质量检查。为此程序员要充分了解软件的质量因素,只有提高设计水平,才能开发出高质量的软件。
【第四章】可行性分析与需求分析
可行性分析是要决定“做还是不做”。
需求分析是要决定“做什么,不做什么”。
即使可行性分析是客观的、科学的,但决策仍有可能是错误的。
4.1可行性分析的要素
做可行性分析不能以偏盖全,也不可以什么鸡毛蒜皮的细节都加以权衡。可行性分析必须为决策提供有价值的证据。一般地,软件领域的可行性分析主要考虑四个要素:经济、技术、 会环境和人
【一,经济】经济可行性分析主要包括:“成本——收益”分析和“短期——长远利益”分析
【二,技术】技术可行性分析可以简单地表述为:做得了吗得好吗得快吗br> 【三, 会环境】 会环境的可行性至少包括两种因素:市场与政策。
市场又分为未成熟的市场、成熟的市场和将要消亡的市场。政策对软件公司的生存与发展影响非常大
【四,人】有句名言:“人分四类——人物,人才,人手,人渣。”
如果一个软件公司里上述四类人齐全了,那么最好的分工是让“人物”当领导,“人才”做第一线的开发人员,“人手”做行政人员,“人渣”负责行贿。
4.2需求分析案例
4.3需求分析为什么困难
有几种原因使需求分析变得困难:(1)客户说不清楚需求;(2)需求自身经常变动;(3)分析人员或客户理解有误。
A.)尽可能地分析清楚哪些是稳定的需求,哪些是易变的需求。以便在进行系统设计时,将软件的核心建筑在稳定的需求上,否则将会吃尽苦头。
B)在合同中一定要说清楚“做什么”和“不做什么”。如果合同含含糊糊,日后扯皮的事情就多。要防止象韩复渠那样,在别人请他喝酒吃饭时他什么都点头(人家就更加献殷勤),吃完了他就宣布刚才答应的事都不算数,便扬长而去。
4.4 如何进行需求分析
我们要围绕两个核心问题开展需求分析:(1)应该了解什么2)通过什么方式去了解br> 【应该了解什么】
需求分析不象侦探推理那样从蛛丝马迹着手。应该先了解宏观的问题,再了解细节的问题
一个软件系统(记为 S)的涉及面可能很广,可以按不同的问题域(记为D)分类,每个问题域对应于一个软件子系统。
S = { D1,D2,D3,… Dn }
问题域Di 由若干个问题(记为P)组成,每个问题对应于子系统中的一个软构件。
Di = { P1,P2,P3,… Pm }
问题Pj有若干个行为(或功能,记为F),每个行为对应于软构件中的接口。
Pj = { F1,F2,F3,… Fk }
按图4.1结构写成的需求说明书,对于那些只想了解宏观需求的领导,和需要了解细节的技术员都合适。在写需求说明书时还应该注意两个问题:
(1)最好为每个需求注释“为什么”,这样可让程序员了解需求的本质,以便选用最合适的技术来实现此需求。
(2)需求说明不可有二义性,更不能前后相矛盾。如果有二义性或前后相矛盾,则要重新分析此需求。
【通过什么方式去了解】
了解需求的方式有好几种:
(1)直接与客户交谈。如果分析人员生有足球评论员的那张“大嘴”,就非常容易侃出需求。
(2)有些需求客户讲不清楚,分析人员又猜不透,这时就要请教行家。有些高手真的很厉害,你还没有开始问,他就能讲出前因后果。让你感到“听君一席言,胜读十年书。”
(3)有很多需求可能客户与分析人员想都没有想过,或者想得太幼稚。要经常分析优秀的和蹩脚的同类软件,看到了优点就尽量吸取,看到了缺点就引以为戒。前人既然付了学费,后人就不要拒绝坐享其成。
小结:如果您学会了客观、科学的可行性分析,在作决策时就要果断,要学习热恋中的这个年青人——
“倒底行还是不行就结婚,不行就离婚。”
【第五章】系统设计
系统设计是把需求转化为软件系统的最重要的环节。系统设计的优劣在根本上决定了软件系统的质量。就象“一切帝国主义都是纸老虎”那样可以断定“差的系统设计必定产生差的软件系统。”所以我们要努力保证系统设计“根正苗红”,把一切左倾、右倾的设计思潮消灭在萌芽状态
本章讲述系统设计的四方面内容:体系结构设计、模块设计、数据结构与算法设计、用户界面设计。如果将软件系统比喻为人体,那么:
(1)体系结构就如同人的骨架。如果某个家伙的骨架是猴子,那么无论怎样喂养和美容,这家伙始终都是猴子,不会成为人。
(2)模块就如同人的器官,具有特定的功能。人体中最出色的模块设计之一是手,手只有几种动作,却能做无限多的事情。人体中最糟糕的模块设计之一是嘴巴,嘴巴将最有价值但毫无相干的几种功能如吃饭、说话、亲吻混为一体,使之无法并行处理,真乃人类之不幸。
(3)数据结构与算法就如同人的血脉和神经,它让器官具有生命并能发挥功能。数据结构与算法分布在体系结构和模块中,它将协调系统的各个功能。人的耳朵和 嘴巴虽然是相对独立的器官,但如果耳朵失聪了,嘴巴就只能发出“啊”“呜”的声音,等于丧失了说话的功能(所以聋子天生就是哑巴),可人们却又能用手势代 替说话。人体的数据结构与算法设计真是十分神奇并且十分可笑。
(4)用户界面就如同人的外表,最容易让人一见钟情或一见恶心。象人类追求心灵美和外表美那样,软件系统也追求(内在的)功能强大和(外表的)界面友好。
【一,体系结构设计】
杨叔子院子曾这样指点其弟子:
文学中有科学,音乐中有数学,漫画中有现代数学的拓扑学。漫画家可以“几笔”就把一个人画出来,不管怎么美化或丑化,就是活像。为什么为那“几笔”不是别的,而是拓扑学中的特征不变量,这是事物最本质的东西。
体系结构是软件系统中最本质的东西:
(1)体系结构是对复杂事物的一种抽象。良好的体系结构是普遍适用的,它可以高效地处理多种多样的个体需求。一提起“房子”,我们的脑中马上就会出现房子的印象(而不是地洞的印象)。“房子”是人们对住宿或办公环境的一种抽象。不论是办公楼还是民房,同一类建筑物(甚至不同类的建筑物)之间都具有非常相似的体系结构和构造方式
(2)体系结构在一定的时间内保持稳定。只有在稳定的环境下,人们才能干点事情, 会才能发展。
良好的体系结构意味着普适、高效和稳定。
本节将论述两种非常通用的软件体系结构:层次结构和客户机/服务器(Client/Server)结构。
1.层次结构
层次结构表达了这么一种常识:有些事情比较复杂,我们没法一口气干完,就把事情分为好几层,一层一层地去做。高层的工作总是建立在低层的工作之上。层次关系主要有两种:上下级关系(上层子系统可以使用下层子系统的功能,而下层子系统不能够使用上层子系统的功能)和顺序相邻关系(顺序相邻关系的层次结构表明通讯只能在相邻两层之间发生,信息只能被一层一层地顺序传递。这种层次结构的经典之作是计算机 络的OSI参考模型)。
1.1其它的层次结构
目前在大型商业应用软件系统中还流行一种包含中间件(Middleware)的层次结构,如图5.3所示[Jacobson 1997]。中间件支持与平台无关的分布式计算,可以用DCOM和CORBA对象来实现。
Application Systems
Business-specific Components
Middleware
System Software
2.客户机/服务器结构
客户机/服务器结构存在两个显然的优点:
(1)以集中的方式高效率地管理通讯。前面讲电话系统的故事就是要说明这一点。
(2)可以共享资源。比如在信息管理系统中,服务器将信息集中起来,任何客户机都可以通过访问服务器而获得所需的信息。
客户机和服务器之间的通讯以“请求——响应”的方式进行。客户机先向服务器发起“请求”(Request),服务器再响应(Response)这个请求。 采用“请求——响应”这种通讯方式的基本动机是为了解决“聚集”(Rendezvous)问题。在客户机/服务器结构中,服务器在启动后必须(无限期地) 等待客户机的“请求”,因此就形成了“请求——响应”的通讯方式。
在Internet/Intranet领域,目前“浏览器—Web 服务器—数据库服务器” 结构是一种非常流行的客户机/服务器结构。这种结构最大的优点是:客户机统一采用浏览器,这不仅让用户使用方便,而且使得客户机端不存在维护的问题。当 然,软件开发布和维护的工作不是自动消失了,而是转移到了Web 服务器端。在Web 服务器端,程序员要用脚本语言编写响应页面。例如用Microsoft的ASP语言查询数据库服务器,将结果保存在Web 页面中,再由浏览器显示出来。
【二,模块设计】
在 设计好软件的体系结构后,就已经在宏观上明确了各个模块应具有什么功能,应放在体系结构的哪个位置。我们习惯地从功能上划分模块,保持“功能独立”是模块 化设计的基本原则。因为,“功能独立”的模块可以降低开发、测试、维护等阶段的代价。但是“功能独立”并不意味着模块之间保持绝对的孤立。一个系统要完成 某项任务,需要各个模块相互配合才能实现,此时模块之间就要进行信息交流。
评价模块设计优劣的三个特征因素:“信息隐藏”、“内聚与耦合”和“封闭——开放性”。
A信息隐藏
在一节不和谐的课堂里,老师叹气道:“要是坐在后排聊天的同学能象中间打牌的同学那么安静,就不会影响到前排睡觉的同学。”
这个故事告诉我们,如果不想让坏事传播开来,就应该把坏事隐藏起来,“家丑不可外扬”就是这个道理。为了尽量避免某个模块的行为去干扰同一系统中的其它模块,在设计模块时就要注意信息隐藏。应该让模块仅仅公开必须要让外界知道的内容,而隐藏其它一切内容。
模块的信息隐藏可以通过接口设计来实现。一个模块仅提供有限个接口(Interface),执行模块的功能或与模块交流信息必须且只须通过调用公有接口来实现。
B内聚与耦合
内聚(Cohesion)是一个模块内部各成分之间相关联程度的度量。耦合(Coupling)是模块之间依赖程度的度量。内聚和耦合是密切相关的,与其它模块存在强耦合的模块通常意味着弱内聚,而强内聚的模块通常意味着与其它模块之间存在弱耦合。模块设计追求强内聚,弱耦合。
一、内聚强度
内聚按强度从低到高有以下几种类型:
(1)偶然内聚。如果一个模块的各成分之间毫无关系,则称为偶然内聚。
(2)逻辑内聚。几个逻辑上相关的功能被放在同一模块中,则称为逻辑内聚。如一个模块读取各种不同类型外设的输入。尽管逻辑内聚比偶然内聚合理一些,但逻辑内聚的模块各成分在功能上并无关系,即使局部功能的修改有时也会影响全局,因此这类模块的修改也比较困难。
(3)时间内聚。如果一个模块完成的功能必须在同一时间内执行(如系统初始化),但这些功能只是因为时间因素关联在一起,则称为时间内聚。
(4)过程内聚。如果一个模块内部的处理成分是相关的,而且这些处理必须以特定的次序执行,则称为过程内聚。
(5)通信内聚。如果一个模块的所有成分都操作同一数据集或生成同一数据集,则称为通信内聚。
(6)顺序内聚。如果一个模块的各个成分和同一个功能密切相关,而且一个成分的输出作为另一个成分的输入,则称为顺序内聚。
(7)功能内聚。模块的所有成分对于完成单一的功能都是必须的,则称为功能内聚。
二、耦合强度
耦合的强度依赖于以下几个因素:(1)一个模块对另一个模块的调用;(2)一个模块向另一个模块传递的数据量;(3)一个模块施加到另一个模块的控制的多少;(4)模块之间接口的复杂程度。
耦合按从强到弱的顺序可分为以下几种类型:
(1)内容耦合。当一个模块直接修改或操作另一个模块的数据,或者直接转入另一个模块时,就发生了内容耦合。此时,被修改的模块完全依赖于修改它的模块。
(2)公共耦合。两个以上的模块共同引用一个全局数据项就称为公共耦合。
(3)控制耦合。一个模块在界面上传递一个信 (如开关值、标志量等)控制另一个模块,接收信 的模块的动作根据信 值进行调整,称为控制耦合。
(4)标记耦合。模块间通过参数传递复杂的内部数据结构,称为标记耦合。此数据结构的变化将使相关的模块发生变化。
(5)数据耦合。模块间通过参数传递基本类型的数据,称为数据耦合。
(6)非直接耦合。模块间没有信息传递时,属于非直接耦合。
如果模块间必须存在耦合,就尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,坚决避免使用内容耦合。
C封闭——开放性
如果一个模块可以作为一个独立体被其它程序引用,则称模块具有封闭性。如果一个模块可以被扩充,则称模块具有开放性。
从字面上看,让模块具有“封闭——开放性”是矛盾的,但这种特征在软件开发过程中是客观存在的。当着手一个新问题时,我们很难一次性解决问题。应该先纵观 问题的一些重要方面,同时作好以后补充的准备。因此让模块存在“开放性”并不是坏事情。“封闭性”也是需要的,因为我们不能等到完全掌握解决问题的信息后 再把程序做成别人能用的模块。
模块的“封闭——开放性”实际上对应于软件质量因素中的可复用性和可扩充性。采用面向过程的方法进行程序设计,很难开发出既具有封闭性又具有开放性的模块。采用面向对象设计方法可以较好地解决这个问题。
【三、数据结构与算法设计】
学会设计数据结构与算法,可以让我们编写出高效率的程序,
设计高效率的程序是基于良好的数据结构与算法,而不是基于编程小技巧。
一般说来,数据结构与算法就是一类数据的表示及其相关的操作(这里算法不是指数值计算的算法)。从数据表示的观点来看,存储在数组中的一个有序整数表也是一种数据结构。算法是指对数据结构施加的一些操作,例如对一个线性表进行检索、插入、删除等操作。一个算法如果能在所要求的资源限制(Resource Constraints)范围内将问题解决好,则称这个算法是有效率(Efficient)的。例如一个资源限制可能是“用于存储数据的内存有限”,或者“允许执行每个子任务所需的时间有限”。一个算法如果比其它已知算法所需要的资源都少,这个算法也被称为是有效率的。算法的代价(Cost)是指消耗的资源量。一般说来,代价是由一个关键资源例如时间或空间来评估的。
人们对常用的数据结构与算法的研究已经相当透彻,可以归纳出一些设计原则:
(1)每一种数据结构与算法都有其时间、空间的开销和收益。当面临一个新的设计问题时,设计者要彻底地掌握怎样权衡时空开销和算法有效性的方法。这就需要懂得算法分析的原理,而且还需要了解所使用的物理介质的特性(例如,数据存储在磁盘上与存储在内存中,就有不同的考虑)。
(2)与开销和收益有关的是时间——空间的权衡。通常可以用更大的时间开销来换取空间的收益,反之亦然。时间——空间的权衡普遍地存在于软件开发的各个阶段中。
(3)程序员应该充分地了解一些常用的数据结构与算法,避免不必要的重复设计工作。
(4)数据结构与算法为应用服务。我们必须先了解应用的需求,再寻找或设计与实际应用相匹配的数据结构。[Shaffer 1998]
【四、用 户 界 面 设 计】
【第六章】C++程序设计
【第七章】测试与改错
错误是一种严重的程序缺陷。测试的目的是为了发现尽可能多的缺陷,并期望通过改错来把缺陷统统消灭,以期提高软件的质量。测试的目的是为了发现尽可能多的缺陷。
这里缺陷是一种泛称,它可以指功能的错误,也可以指性能低下,易用性差等等。测试总是先假设程序中存在缺陷,再通过执行程序来发现并最终改正缺陷。理解测试的目的是个
很重要的意识问题。
测试的主要内容与常用方法
正确性测试
正确性测试又称功能测试,它检查软件的功能是否符合规格说明。由于正确性是软件最重要的质量因素,所以其测试也最重要。
基本的方法是构造一些合理输入,检查是否得到期望的输出。
容错性测试
容错性测试是检查软件在异常条件下的行为。容错性好的软件能确保系统不发生无法意料的事故。
性能与效率测试
性能与效率测试主要是测试软件的运行速度和对资源的利用率。有时人们关心测试的“绝对值”,如数据送输速率是每秒多少比特。有时人们关心测试的“相对值”,如某个软件比另一个软件快多少倍。
性能与效率测试中很重要的一项是极限测试,因为很多软件系统会在极限测试中崩溃。例如,连续不停地向服务器发请求,测试服务器是否会陷入死锁状态不能自拔;给程序输入特别大的数据,看看它是否吃得消。
易用性测试
易用性测试没有一个量化的指标,主观性较强。调查表明,当用户不理解软件中的某个特性时,大多数人首先会向同事、朋友请教。要是再不起作用,就向产品支持部门打电话。只有30%的用户会查阅用户手册。
一般认为,如果用户不翻阅手册就能使用软件,那么表明这个软件具有较好的易用性。
文档测试
文档测试主要检查文档的正确性、完备性和可理解性。好多人甚至不知道文档是软件的一个组成部分。
正确性是指不要把软件的功能和操作写错,也不允许文档内容前后矛盾。
【改错】
总结关于改错的几点思想方法
(1)要有勇气
(2)不可蛮干
(3)找出错误的根源,我们应该运用归纳、推理等方法尽早确定错误的根源。
(4)在改错之后一定要马上进行重新测试,以免引入新的错误。
程序出了错误一定要改错,但是“编写优质无错”的程序才是根本的解决之道
文章知识点与官方知识档案匹配,可进一步学习相关知识算法技能树首页概览34188 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!