本篇博客意在对比软件工程领域的结构化方法与面向对象化方法,在开始对比以前咱们要先知道这些方法出现的背景,并对这两种方法有一个大体的了解。下面先让咱们来一块儿探究一下它们出现的背景。java
对于软件工程领域而言,它的终极目标是:有效地获得一个运行的系统及其技术支持文档,同时该系统须要知足有关的质量要求。web
这样的系统就是软件开发方法最终须要达到的目标。在达到这个最终目标的过程当中,咱们须要实施一系列的软件活动,包括设计,约定接口,制定编程规范等。软件的需求越多,体积越庞大,咱们实施的软件活动自己的复杂性也就越高。为了可以有效地组织起软件生存周期中这些活动的实施,咱们须要选择相应的组织框架,进而造成特定的项目生存周期的过程。这也就是结构化方法和面向对象化方法自己的意义所在,它们能够帮助咱们更好地规划与管理软件工程中具体活动的实施。算法
不少人都以为本身未曾在软件工程中使用过结构化的或面向对象化的方法,博主猜想他们这么体会的主要缘由多是他们并无实施过完整的软件构建流程,而仅仅是将软件看成了一段程序来写。数据库
写一段程序和构建一个软件是有很大不一样的,拿ACM竞赛中的比赛程序举例,这些程序都有固定的每每不带提示信息的输入与输出,程序写得好与很差主要取决于算法的性能,有些时候也会参考代码的风格。但它们相比软件很大的不一样之处在于:程序不须要考虑用户输入,也不须要考虑用户体验。可是软件工程活动构建的产物——由需求而非输入输出定义的软件须要这些额外的东西。编程
而构建一个软件则须要细致的计划,编写,测试等,下面就来一块儿看一下结构化方法吧。后端
通常来讲软件的生命周期能够被划分为:软件计划,软件分析,软件设计,实际编码,软件测试(包括了黑盒,白盒,单元,回归测试等)及运行维护等阶段表示。结构化方法包含了其中的两个部分:软件工程结构化分析(structured analysis,SA) 以及 软件工程结构化设计(structured design,SD)。浏览器
结构化分析是结构化方法的一部分,其主要目标是系统化地使用给定的信息,可以造成对问题的估算求解。缓存
举个例子,对于软件工程中的需求分析环节,咱们如何结构化分析呢?服务器
在结构化分析中有三个要素,分别是:数据结构
下面针对这些咱们来逐一阐释这些问题,首先的问题是在结构化分析中须要使用到的信息。
结构化分析方法中有五个必要的组成元素,分别是:
这几个基本术语都比较抽象,咱们举个例子来讲明一下它们在现实生活中的映射。
好比咱们要设计一个简单的门系统,这个系统的需求看起来很明确:门嘛,相信正常人都会理解。但实际上所谓的这个门系统就只是定义了一个模糊的抽象层而已,它定义了:
Markdown
或者其余富文本格式,博客文本做为数据在博主与博客园之间流动。而在其余人浏览时,博客园从后端取出博客内容,为博客加上CSS样式,最后由浏览器渲染展现给浏览的人,这其中数据以HTML的格式从博客园的服务器流向了用户的浏览器,这是另外一种数据的流动。刚刚咱们提到了五个抽象的名词,那么在实际使用中,对于这些信息流的抽象层咱们该如何发挥他们的做用。换句话说,咱们该如何系统化地使用这些信息?这时模型表达工具就颇有用了。在结构化的方法中通常使用三种模型表达工具:
在这三种模型表达工具中,数据流图和数据字典在数据库的设计中可能出现频率更高些,这两种模型工具与数据自己关系很紧密。
这三种模型表达工具结合起来涵盖了系统总体建模的整个流程,下面让咱们来使用结构化方法完成一个完整的建模过程。
在对总体建模时,咱们首先要借助数据流图构建一个系统功能模型。要完成系统功能模型,咱们首先要肯定系统的边界——数据源和数据潭;在区分好系统和其边界后,也就建好了系统的顶层流图,这是再开始对整个系统自顶向下逐步求精地创建系统的层次数据流图。这里体现了咱们结构化分析方法中的一个重要思想:自顶向下,逐层分解。
咱们依旧用博客系统来举例,若是要咱们创建一个简单的博客系统,其中:
根据需求画出其数据流图以下:
这时咱们的顶层数据流图就已经完成了,但由于此时咱们只有一个需求明确,数据操做并不明确的系统。接下来咱们就须要将这个模糊不清的系统的功能细化,将不一样的数据流与不一样的操做链接,而非只是跟系统这个黑盒相连。
咱们将博客系统分红两部分,一部分是文章系统,一部分是评论系统,而后将这两部分与它们分别对应的数据流相连,就能够造成一个具体一点的系统,以下图所示。
在完成数据流图的构建后,咱们须要使用数据字典来定义数据流、数据存储和数据项。
好比博客 = 博客标题 + 博客正文 + 博客做者 + 时间戳
这就是一个简单的数据字典的定义。
最后须要为数据加工添加约束条件,好比博客的正文必须大于十个字才能发布,与上一次博客编辑的时间差要大于10s才能更新等。
说完告终构化分析,下面咱们来说讲结构化设计。
与结构化结构化设计的主要目标就是给出一个软件的解决方案,它主要分为两个主要部分:
这两部分关系是由上到下的,先进行系统的设计,再进行各个模块的设计,同时也映证告终构化方法的基本原则之一:自顶向下功能分解。
在系统设计中,主要目标是用于肯定各个模块之间的调用关系和系统的总体结构。因为结构化分析中获得的数据流图并不能彻底匹配结构化设计的需求,系统设计的目标就是为了过渡这种差别,将上述结构化分析获得的数据流图转换为模块图以供进一步设计。在结构化设计中常采用结构图来描述程序的结构。
结构图的基本成分有模块、调用和数据。下面是一个结构图的示例
在结构化设计中有一个很是重要的原则,那就是基于模块化原理的高内聚,低耦合。
将数据流图中直接转换获得的各个子模块进行改进,经过模块的分解和合并,力求下降耦合,提升内聚。好比说能够将多个模块公用的子功能能够独立造成一个模块,供这些模块调用。
结构化设计的目标是将一个初始的模块结构图转换为最终的模块结构图,并把各个模块的描述不清的需求肯定下来,因此对于设计人员来讲结构化设计是一种挑战,设计的质量将直接影响软件系统开发的质量。
介绍完告终构化方法,下面来粗略了解一些面向对象的方法。
面向对象方法的出现晚于结构化方法,但其发展壮大之迅速是软件开发领域的一个奇迹。它的概念很是明确,它是一种运用对象、类、继承、封装、聚合、 关联、消息、多态性 等概念来构造系统的软件开发方法(引自《面向对象的系统分析(第2版)》,邵维忠, 杨芙清著,清华大学出版社,2006.12.)。在这里博主不展开讲面向对象分析与面向对象设计方法,主要讲述一些它的特色,觉得后面的对比进行铺垫。
在面向对象方法中,最重要的概念就是对象的概念:对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。
对象是构成世界的一个独立的单位,它具备两方面的特征,一方面是静态特征,另外一方面是动态特征。
面向对象的方法中对象的属性和操做是合为一体的,它们一块儿构成一个独立的实体。对象内部细节对外部来讲是不可见的,对象自动维护本身的状态使本身保持正常运转,外部不须要维护对象的状态变化。
上面咱们初步了解了两种方法,如今让咱们来一块儿看一下它们的差异。
对于结构化方法,一切系统都是由信息流构成的。信息流中既包含了一些必要的数据变换,每一个信息流都有本身的起点和归宿,又包含了驱动信息流动的数据操做。整个系统能够被看做是经过数据操做把流动的信息流来组织起来的模型。
因此在结构化方法中,信息流的概念很重要,不管是在分析仍是在设计时咱们都须要当心翼翼地对待信息流动的方法,源头,终点。
而在面向对象方法中,一切系统都是由对象构成的。对象之间的相互做用和相互影响构成了各式各样复杂多变的系统.
结构化的设计关注的是事件的发生,因此更像是面向过程程序设计的风格,好比说C程序的风格。面向对象的设计关注的是对象的功能,好比说Java程序的风格。
在我看来,结构化方法更像是小说,而面向对象的方法更偏向于产品说明书。
提及小说,小说三要素分别是:人物,环境与故事情节。
人物
身上的方法小说该如何吸引人呢?须要咱们的人物形象刻画丰满、故事情节动人,均可以吸引咱们。所以在咱们阅读小说的时候,注重更多的是发生在这我的物身上的情节,固然,环境对于整个故事的推动也很重要。联系面向过程的程序,一个面向过程的程序描写的是什么——以C语言为例,一个主函数,定义局部变量、全局变量,而后调用子函数,子函数的目的是对变量、数据结构进行操做,是发生在该变量以及该数据结构身上的事情,在主函数中,
void open(Door *door) { // do... } int main() { // do... open(_door); // do... }
这段代码描述的是门的“开”行为:一个行为“开”发生在了门上。这是一个故事情节,讲述了这个行为的发生。面向过程关注的是过程的发生,针对咱们的软件来讲,就是:你有什么样的情节,就编写什么样的软件。
而产品说明书,很明显是在描述一个产品的属性。一个产品的规格如何、他有什么样的功能,列齐了在一个表上,至于你怎么使用那就是使用者的,我把这个产品的规格、功能都呈现给你,随便你去用。不是说用private
保护起来就叫作封装了,它是用来区份内外的。对于外部的调用者,对象自己提供的就是一张产品使用说明书,你只须要知道怎么用,门怎么开,须要多大的力度,门把手须要转多少度,角度最大能长多大,这些都是产品自身的属性。举个例子:
class Door { void open() { // do... } }
这就比如是一张产品的说明书,这个产品的名字叫Door,它呈现的是open这个接口,外部调用者只须要知道,哦,这个东西能够开啊。而对于门来讲,它也不care外部是谁在用,它只须要在open时状态正常就能够了。封装区份内外,内部我来维护、外部我无论,当我修改了open内部的东西时,外部的人根本看不出来我改了,他该用照经常使用,这是由面向对象带来的可维护性。
对于结构化设计来讲,由于其建模所须要的就是“过程”和“数据”,而在客观事物中过程与数据偏偏是最容易变化的性质,因此结构化方法的可维护性就要比面向对象的方法可维护性要差。改动A的同时须要B、C分别做出相应的改动。因此在可维护性上,结构化方法不如面向对象的方法。
在上面咱们提到告终构化方法的可维护性较差,在这个需求变化愈来愈快的时代显得力不从心。可是结构化的设计方法必然是有其优势和长处才能依然立足于软件工程领域的,也是C/C++语言一直被用做底层语言的一个重要特色:足够快,性能高。
1980年至今,CPU性能提升了近10W倍,但内存的访问性能和效率只提升了不足100倍,主要缘由其实并不在于内存部件进展较慢,而在于程序对内存的访问效率大大下降。而面向对象方法的一些弊端由于其特性的滥用而凸显出来。与结构化须要即访问不一样,面向对象程序要通过不少间接过程才能访问到目标内存地址,这种间接使得有些时候程序并不能充分利用硬件的最佳性能。面向对象方法的性能问题主要体如今如下方面:
过分封装。从好的方面来讲,封装简化了系统设计,将复杂问题抽象成较简单的独立对象,经过对象的相互调用去实现方案,但因为对象包含本身封装的数据,使得运行一个逻辑时数据会分散在不一样的内存区域,会产生较多的Cache Miss。
数据布局。咱们通常会认为,将相互之间关联的数据紧凑地放在一块儿对缓存友好,然而,在实际应用场景中,咱们须要考虑数据的存取模式。一般来讲,面向对象中一个方法只会访问一个对象不多的数据,却由于数据布局的问题不得不载入大量的无关数据,这对于缓存是很是不利的。
结构化方法从本质上说与Cache设计的基本原则局部性原理契合,因此结构化的方法更符合计算机的本质,因此它更快;而面向对象化的方法更符合人的思惟方式,更有利于代码的实现。
经过以上对比分析咱们能够得出一个直观结论:在应用时,对于更接近底层的软件系统,如Linux系统这种对性能要求较高且与计算机核心息息相关的系统,以及那些对代码和可维护性并无太高要求的(好比一些小型的大做业工程)通常使用结构化的方法和编程模型指导设计就能够;而对于大型的偏向应用层的软件,好比像Office系列软件等须要多人协做,对性能速度要求没有苛刻要求的,为了代码的可维护性与健壮性,使用面向对象的方法更适合。
以上是博主综合了一些文献和博客思考得出的结论,欢迎各位指正。