首页 代码大全 java

代码大全 java

举报
开通vip

代码大全 java代码大全 java 第六章 模块化设计 目录 6.1 模块化:内聚性与耦合性 6.2 信息隐蔽 6.3 建立模块的理由 6.4 任何语言中实现模块 6.5 小结 相关章节 高质量子程序的特点:见第5章 高层次设计:见第7章 抽象数据类型:见第12.3节 “你已经把你的子程序放入我的模块中” “不,你已经围绕着我的子程序设计好了模块” 人们对于子程序和模块之间的区别往往不很注意,但事实上应该充分了解它们之间的区别, 以便尽可能地利用模块所带来的便利。 “Routine”和“Modu1e...

代码大全  java
代码大全 java 第六章 模块化 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 目录 6.1 模块化:内聚性与耦合性 6.2 信息隐蔽 6.3 建立模块的理由 6.4 任何语言中实现模块 6.5 小结 相关章节 高质量子程序的特点:见第5章 高层次设计:见第7章 抽象数据类型:见第12.3节 “你已经把你的子程序放入我的模块中” “不,你已经围绕着我的子程序设计好了模块” 人们对于子程序和模块之间的区别往往不很注意,但事实上应该充分了解它们之间的区别, 以便尽可能地利用模块所带来的便利。 “Routine”和“Modu1e”这两个单词的意义是很灵活的,在不同的环境下,它们之间的区 别可能会变化很大。在本书中,子程序是具有一定功能的,可以调用的函数或过程,关于这一 点在第五章已经论述过了。 而模块则是指数据及作用于数据的子程序的集合。模块也可能是指,可以提供一系列互相 联系功能的子程序集合,而这些子程序之间不一定有公共的数据。模块的例子有:C语言中的 源文件,某些Pascal版本中的单元及Ada语言中的“包”等等。如果你所使用的语言不直接支 持模块,那么可以通过用分别编程技术来模仿它,这也可以得到许多由模块带来的优点。 6.1 模块化:内聚性与耦合性 “模块化”同时涉及到子程序设计和模块设计。这是一种值得研究的,非常有用的思想方 法。 在1981年出版的《Software Maintenance Guidebook》一书中,Glass和Noiseux认为模 块化给维护性带来的好处要比给结构带来的好处多得多,它是提高维护性的最重要因素。Lientz 和Swanson在《Software Maintenance Management》一书中引用的一项研究表明,89%的代码使 用者认为使用模块化编程改进了维护性(1980)。在一次理解测验中发现,采用模块化设计程序 的可读性要比不采用这种设计的程序可读性高15%(1979)。 模块化设计的目标是使每个子程序都成为一个“黑盒子”,你知道进入盒子和从盒子里出来 的是什么,却不知道里边发生什么。它的接口非常简单,功能明确, 对任何一个特定的输入, 你都可以精确地预测它相应的输出结果。如果你的子程序像一个黑盒子,那么它将是高度模块 化的,其功能明确,接口简单,使用也灵活。 使用单独一个子程序是很难达到这一目的的,这也正是引入模块的原因。一组子程序常常 要使用一套公用的数据,在这种情况下,由于子程序间要共享数据,因而它们不是高度模块化 的,作为一个单个的子程序,它们的接口也不简单。但是,作为一个整体,这组子程序则完全 有可能为程序的其它部分提供一个简单的接口,也完全有可 6.1.1 模块内聚性 模块的内聚性准则,与单个子程序的内聚性准则一样,都是十分简单的。一个模块应该提 供一组相互联系的服务。 比如一个进行驾驶控制模拟的模块,其中应含有描述汽车目前的控制设置和目前速度的数 据。它可以提供像设定速度、恢复到刚才的速度、刹车等功能。在其内部,可能还有附加的子 程序和数据来支持这些功能,但是,模块外的子程序则不需对它们有任何了解。如果这样的话, 那么这个模块的内聚性将是非常强的,因为模块中的每个子程序都是为提供驾驶控制模拟服务 的。 再比如一个进行三角函数计算的子程序,模块中可能含有Sin()、Cos()、Tan()、Arcsin()等 全部密切相关的三角函数子程序。如果这些子程序都是 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 的三角函数,那么它们无须共享数 据,但这些子程序间仍然是有联系的,因此这个模块的内聚性仍然是非常强的。 下面是一个内聚性不好的模块例子,设想一个模块中含有几个子程序为实现一个堆栈: init_stack()、push()和pop();模块中同时还含有 格式 pdf格式笔记格式下载页码格式下载公文格式下载简报格式下载 报告 软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载 数据和定义子程序中用到的所有全局 数据的子程序。很难看出堆栈与报告子程序或全局数据部分有什么联系,因此模块的内聚性是 很差的。这些子程序应该按照模块中心的原则进行重新组织。 在上例中,对模块内聚性的估计是以模块数据和功能为基础进行的。 它是在把模块作为一 个整体的层次上进行的。因而,模块中的子程序并不会因为模块内聚性好而一定具有良好的内 聚性。所以模块中的每个子程序设计,也要以保证良好内聚性为准则。关于这方面的问题,见 5.3节“强内聚性”。 6.1.2 模块耦合 模块与程序其它部分间的耦合标准与子程序间的耦合标准也是类似的。模块应被设计成可 以提供一整套功能,以便程序的其它部分与它清楚地相互作用。 在上述的驾驶控制例子中,模块担任了如下功能:SetSpeed()、GetCurrentSettings()、 ResumeFormerSpeed()和Deactivate()。这是一套完整的功能,因而程序的其它部分与它的相互作 用完全是通过规定的公用接口进行的。 如果模块所提供的功能是不完善的,其它子程序可能被迫对其内部数据进行读写操作。这 就打开了黑盒子盖而使其成为透明的了,这实际上破坏了模块化。结 构化设计的先驱Larry Constantine指出,模块提供的功能必须是完整的,以便它的调用者们可以各取所需。 为了设计出强内聚而又松散耦合的模块,必须在设计模块和设计单个子程序的标准之间进 行平衡与折衷。降低子程序之间耦合性的重要措施之一,就是尽可能建模块的原因之一则是为了让子程序可以共享数据;你若想使同一模块中的子程序不必通过参 数表进行传递,可以采用对其中所有数据进行直接存取来实现。 从所有模块中的子程序可以对它进行存取的角度来说,模块中数据很像是全局数据。但从 不是程序中所有的子程序都可以对它进行存取的角度来说,它又不像是全局数据,它只对模块 中的子程序来说,才是可以存取的。因此,在模块设计中的最重要决定之一,便是决定哪个子 程序需要对模块中数据进行直接存取。如果某个子程序仅仅是由于可以对模块中数据进行存取 的原因才留在模块中的,那么,它应该被从模块中去掉。 6.2 信息隐蔽 如果你阅读了书中所有推荐参阅文献的注释,你就会发现其中有400多个是关于信息隐 蔽的。拥有这么多参考文献的内容一定是非常重要的吧,是的,它的确非常重要。 进行信息隐蔽的设计思想贯穿了软件开发的每一个层次,从使用命名的常量而不是使用自 由常量到子程序设计、模块设计和整个程序设计。由于这一思想往往是在模块这一层次得到最 充分体现的。因此,我们在本章详细讨论它。 信息隐蔽是为数不多的几个在实践中无可辩驳地证明了自己价值的理论之一(Boehm 1987)。研究发现,应用信息隐蔽进行设计的大型程序容易更改指数要比没采用这一技术的高4 倍。同时,信息隐蔽也是结构化设计和面向对象设什的基础之一。在结构化设计中,黑盒子思 想便来源于信息隐蔽。在面向对象设计中,也是信息隐蔽引发了抽象化和封装化的设计思想。 6.2.1 保密 信息隐蔽中的关键概念是“保密”。每一个模块的最大特点都是通过设计和实现,使它对其 它模块保密。这个秘密或许是可能被改动的区域、某个文件的格式化、一个数据结构的实现方 式、或是一个需要与程序其它部分隔离开来,以便其中的错误产生的危害最小的区域。模块的 作用是将自己的信息隐蔽起来以保卫自己的隐私权。信息隐蔽的另一 个称谓是“封装”,其意思 是一个外表与内容不一样的盒子。 无论管它叫什么,信息隐蔽都是设计子程序和模块的一种方法,它对模块的意义更重要些。 当你隐藏秘密时,你就设计了一组存取同一套数据的子程序。对一个系统的改动可能涉及到几 个子程序,但是,它只应涉及一个模块。 在设计模块时,一项重要任务就是决定哪些特性应该是对模块外部公开的,哪些应该是作 为秘密隐藏起来的,一个模块中可能使用25个子程序而只暴露出其中的5个,其余20个都只 在内部不会提供把数据结构信息通知给程序其余部分的子程序。模块设计的这一方面一般被称作“可 见性”,因为它主要涉及了模块的功能特性是否是对外部分开或暴露的。 模块的接口应该尽可能少地暴露它的内部内容。一个模块应该像是一座冰山,你只看到它 的一角,而它其余7/8的部分则藏在水面下。 与设计的其它方面一样,设计模块的接口也是一个逐渐的过程,如果接口在第一次是不正 确的,可以再试几次直到它稳定下来;如果它稳定不下来,那么就需要重新设计它。 可以用各种不同的图形来代表模块。模块表示图的关键是,它应该区分开仅供模块内部使 用的功能和对外开放的功能。这种图形通常称之为“积木图”,是由Erody Boock在开发Ada 语言过程中提出来的。图6-1表示出了一种模块图。 .ü..?..?..?..?..?.. 其中公用部分是矩形块,个别部分如黑盒子那样表示。 信息隐蔽不必暗示出一个系统的形状;系统可能具有分层结构,也可能像图6-2中所示那 样具有网状结构。 .ü..?..?..?..?..?.. 在网状结构中,你只要规定哪些模块可以与其它模块通信,这种特定的通信是如何进行的, 然后再进行联接的就可以了,如图6-3所示,积木图也可以用在网状结构中。 .ü..?..?..?..?..?.. 文本框: 图6-1 一个模块中公用和个别部分 文本框: 图6-2 网状结构系统 文本框: 图6-3 用包含信息隐蔽思想的符号表示网状系统 6.2.2 信息隐蔽举例 几年前我曾写了一个中型系统(有20K行代码),在其中广泛使用了链表结构。问题域是由 数据结点构成的,每一个结点又与亚坐标、实坐标和等同点相联接。由于我选用了链表结构, 因此在程序中到处都是类似这样的语句: node = node.next and phone = node.data.phone 这些语句直接对链表数据结构进行操作。尽管链表非常自然地将问题进行了模块化,但是 这种方法对内存的使用效率却非常低,于是我想使用整型数组索引来代替内存指针,因为这样 可以提高内存利用率,并且为在其它区域进行性能优化创造机会。但是,由于刚才提到的那种 编码语句充满了程序,因而修改工作非常困难。因为我无法在20000 多行代码中把它们一一找 出来。如果当初我采用了含有如下存取子程序的模块的话,我只要在一个地方即存取子程序中 改动代码就可能了。 node = NearestNeighbor(node) phone = EmergencyContact(node) 我到底赢得了多少内存,我将会赢得或者失去多少速度,我不知道,但是如果当初我了数据结构的细节并且使用了存取子程序,我就可以很容易地找到答案。而且,我还可以尝试 一下另外几种方法。我本来可以从许多 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 中挑选一个最好的,可是,由于我把数据结构的细 节暴露给了整个程序,我不得不使用我所厌恶的方案。 除了方便修改,隐含复杂数据结构细节的另一个重要原因是:隐含细节可以澄清你编写某 段代码的意图。在上例中,一个富有经验的程序员不难读懂下面这条语句的: node = node.next 显然,这个语句指的是一个链表结构,但除此之外,它什么也不能告诉你。然而,一个像 node = NearestNeighbour(node)这样的存取子程序,则清楚描述了链表所代表的内容,因而这是 很有用的,并且提醒你应该对node这个名称进行改进(node与其邻居有什么关系),node = node.text这样的语句与实际相脱离,你根本无法想到应该改进它们的名称以说明实际问题。 隐含数据结构的最后一个原因是出于对可靠性的考虑。如果你用一个专门的子程序来存取 数据结构,你只需在其中设置一个安全验证就可以了。否则,你就不得不在所有这个子程序访 问变量的地方设置安全验证。比如,如果你使用了链表,并且想读取链表中的下一个元素,并 且要注意不超过链表的最后一个元素,你可能用如下的代码: if ( node.text<>null ) then node = node.text 如果在某种情形下,为了更谨慎一些,你可以使用如下代码: if ( node<>null ) then if ( node.next<>null ) then node = node.text 如果你的程序中充斥着node=node.next这样的语句,你可能要在其中某些地方进行测试而 跳过其余部分。但是,如果这个操作是独立在一个子程序调用中: node = NearestNeighbor(node) 那么,你只要在子程序中一个地方进行测试,那么这一测试就会在整个程序中都起作用。 如果有时你想在整个程序中都对使用node的地方进行测试,也很容易漏掉其中某些地方。然而, 如果你把这一操作独立在一个子程序中,那么是不可能有遗漏的,因为此时这项工作完全是自 动进行的。 隐含数据结构细节的另一个好处是容易调试,比如,你发现node值在某处变得有问题了, 但却不知道是在哪里。如果存取node的代码充斥了整个程序的话,那么找到出问题的地方不亚 于大海捞针。但如果它是被孤立在一个子程序中的话,那么你可以在 其中加入一段检查node 的调试码,从而在每次存取它时都进行测试,这样事情就解决了。 应用存取子程序最后一个优点是,可以使所有对数据的存取所遵循的是一种平行的组织形 式;或者通过存取子程序、或者直接对数据的模块内部,对数据的存取都是直接的,在这种情况下失去平行性是不可避免的,这样做的目 的是不在公共场合吹脏肥皂泡。这常常伴随着对在存取程序中进行直接数据操作这一拙劣设计 的隐含。 6.2.3 常见需要隐含的信息 在你所从事的项目中,你可能与不计其数需要隐含的信息打交道,但是,其中只有几种是 你要反复遇到的: ? 容易被改动的区域 ? 复杂的数据 ? 复杂的逻辑 ? 在编程语言层次上的操作 以上每一项都将在下面的部分中给予详细论述。 容易被改动的区域 容易改动是好的程序设计中一项最富于挑战性的工作。目的是将不稳定的区域孤立起来, 以便使改动带来的影响仅限于一个模块中。以下是你在为应付改动的工作中要遵循的步骤。 1( 识别出那些可能被改动的地方。如果分析工作做得很好的话,其中应该附有可能改动 的地方和改动内容的明细表。在这种情况下,找出可能的改动是非常容易的。如果需 求分析中没有进行这项工作,可以参阅下面关于在任何项目中都可能被改动的区域的 讨论。 2( 把可能被改动的地方分离出来。把第一步中发现的每一个可能改动的地方分隔到自己 的模块中,或者将其与其它可能一起被改动的要素一起,独立到一个模块中。 3( 独立可能被改动的地方。应把模块间的接口设计成对可能变动不敏感,同时,接口应 该把变动限制在模块内部,外部不会受到内部变动影响。而其它调用这个被改动过模 块的模块,不应感受到这个模块被修改过。模块的接口应该能保护模块的隐私权。 以下是一些可能变动的区域: 对硬件有依赖的地方。对于监视器、打印机、绘图机等,要清楚在尺寸、颜色、控制代码、 图形能力及内存等方面可能的变化。其余对硬件有依赖性的方面包括与磁盘、磁带、通讯口、 声音器件等接口的变化等等。 输入和输出。在比原始的硬件接口稍高一些的设计层次上,输入/输出是另外一个反复无常 的区域。如果某一应用产生它自己的数据文件,那么当这一应用变得复杂起来时,文件的格式 可能也要变化。用户层次上的输入和输出格式也有可能变化,比如,在打印纸上边界的位置、 每页上边界的数量、域的排列顺序等等。总之,检查所有的外部接口以寻找可能的变化是个好 主意。 非标准语言特性。如果在程序中使用了非标准扩展,应该把这些扩展隐含在一个模块中, 以便当运行环境变化时你可以很容易地替换它。同样,如果你使用了 不是在所有环境下都存的库子程序,应该把实际的库子程序放在另一个环境下也可以使用的接口后面。 难于设计和实现的域。最好把难于设计和实现的域隐含起来,因为此处的工作可能作得很 糟,你可能不得不返工。把它们分隔起来,以便使由于拙劣设计或实现对系统所带来的危害最 小。 状态变量。状态变量指示程序的状态,往往比其它数据更容易被改动。在典型的情形下, 你可能最初把某一错误状态变量定义成逻辑变量。但后来又发现如果把它赋成具有 NoError, WarningError和FatalError三个值的枚举型变量来实现会更好。 你至少可以在使用状态变量时,加上两个层次的灵活性和可读性。 ? 不要使用逻辑型变量作为状态变量,应使用枚举型变量。赋予状态变量一种新状态是 非常常见的,给枚举型变量赋一个新的类型只需要重新编译一次,而对于逻辑型变量 则需要重新编写每行检查状态变量的代码,谁难谁易是很明显的。 ? 使用存取子程序检查变量,而不要对其直接检查,通过检查存取子程序而不是状态变 量,可以进行更复杂的状态测试。例如,如果想检查一个错误状态变量和一个当前函 数状态变量,那么把测试隐含在子程序中来进行,要比用充斥着程序的复杂代码进行 测试容易得多。 数据规模限制。如果你说明一个数组中含有 15个元素,那么你就把系统不需要的信息暴 露给了它。应该保护其隐私权,信息隐蔽并不总是意味着把一系列功能装入模块这类复杂的工 作,有时,它简单到就是用一个像MAX_EMPLOYEES之类的常量来代替15,以便隐含它。 商业规则。商业规则指法律、政策、规定、惯例等编入一个计算机系统中的东西。如果你 在编写一个工资发放系统,你可能把IRS关于允许的扣留数和估计税率等规则编入程序。其余 附加的规则是由工会规定的关于加班率、节假日付酬等方面的规定。如果你正在编写一个引用 保险率的软件,其规定来源于州关于信誉、实际保险率等的管理规定。 这些规定往往是数据处理系统中频繁变动的部分。因为国会可能修改法律,保险公司会调 整保险率。如果你遵从信息隐蔽原则,那么当规则变动时,建立在这些规则上的逻辑关系不会 完全垮掉。这些逻辑关系会隐藏在系统中唯一一个阴暗角落里,直到需对其作出改动为止。 预防到改动。当考虑一个系统中潜在的改动时,应该按照使得改动范围或大小与其改动可 能性成反比的原则来设计系统。如果改动很可能发生,要确保系统可以容易地容纳这一特征。 只有极其不可能发生的变动,才应该被允许在变动时,会影响到系统中一个以 一个寻找可能发生变动域的技术是,首先分析程序中可能会被用户用到的最小的子单元, 这些子单元组成了程序的核心,而且很可能被改变。其次,规定对系统的最小增值。它们可以 小到看起来完全是琐碎的程度。这些潜在改进域组成了对系统的潜在改进。应使用信息隐蔽原 则对这些域进行设计。首先分析核心,可以发现哪些要素事实上是后加上的,从而从那里推测 并隐含改进。 复杂的数据 所有的复杂数据都很可能被改动;如果它很复杂而对它使用得又很多,那么在实现层次 上与其打过交道后,可能会发现实现它的更好方式。如果应用信息隐蔽来隐含数据实现,就 可以付出较少的努力而获得更好的实现方法。如果不是这样,那么你每次与这些数据打交道 时,你可能都会在后悔,如果当初进行了信息隐蔽,改动实现将会是多么容易啊~ 对复杂数据的使用程度,主要取决于程序。如果是一个只有几百行代码的小程序,你想 在其中对变量进行直接操作,那就这样干吧,这样可能影响程序,但也可能不会。在担心由 于对数据直接操作而带来的维护问题之前,应首先考虑这个小程序的特点。如果你正在编写 一个大一些的程序或使用了全局数据,那么就该考虑使用存取子程序。 复杂的逻辑 隐含复杂的逻辑可以改善程序的可读性。复杂的逻辑并不总是程序的最主要方面,把它 隐含起来可以使得子程序的活动更清楚。与复杂数据一样,复杂逻辑也是很可能变动的部分。 所以,把程序的其它部分从这种变动里隔离出去是非常有益的。在某些情况下,你可以将所 使用的逻辑种类隐含起来,例如,你可以通过一个大的if语句、case语句或查表方式来进行 测试。除了这些进行测试的代码外,其余的代码不需要知道这些细节。如果程序中的其余代 码只需要知道结果,那么你就应该仅仅告诉它们结果。 在程序语言层次上的操作 你的程序越是像一个实际问题的解决方案,它就越是不像程序语言结 构的组合,那么, 其质量也就越好,应该把过于专业化的信息隐含起来,比如,下面的 语句: EmployeeID = EmployeeID+1 CurrentEmployee , EmployeeList [ EmployeeID ] 这是一段很不错的程序,但是它是用过于专业化的语言来表达的,应 该用较高程度抽象 的语言来进行这个操作: CurrentEmployee = NextAvailableEmployee() 或者用: CurrentEmployee = NextAvailableEmployee( EmployeeList, EmployeeID ) 通过加入一个隐含了用专业化语言解释正在发生什么的子程序,使得在一个更高的抽象 层次上处理这个问题。这使得你的意图更清 如果用图表来实现一个排序问题。函数HighestPriorityEvent(),LowestPriorityrEvent()和 NextEvent()是抽象函数,隐含了实现细节;而FrontOfQueue(),BackOfQueue()和NextInQueue() 并没有隐含多少细节,因为它们提到了实现,暴露了它们该隐藏的秘密。 一般来说,在设计一组在程序语言语句层次上操作数据的子程序时,应该把对数据操作 隐含在子程序组中,这样程序的其余部分就可能在比较抽象的层次上处理问题了。 6.2.4 信息隐蔽的障碍 绝大多数信息隐蔽障碍都是心理上的,它主要来自于在使用其它技术时形成的习惯。但 在某些情况下,信息隐蔽也的确是不可能的,而一些看起来像是隐蔽障碍的东西,但仅仅是 借口而已。 信息过度分散 信息隐蔽的一个常见障碍是系统中信息过于分散。比如在一个系统中到处分布着常数 100。把100当作一个常数,降低了引用它的集中程度。如果把信息 隐蔽在一个地方会更好, 因为这样它的值将只在一个地方改变。 另一个信息过于分散的例子是程序中分布着与用户交互的接口。如果需要改变交互方式, 比如,从命令行方式改为格式驱动方式,那么所有的代码事实上都要被改动。因此,最好把用 户交互接口放入一个单独的模块中,这样,你不必影响到整个系统就可以对交互方式进行改动。 而还有一个例子则是全局数据结构,比如,一个在整个系统中四处被存取的拥有多达1000 个元素的雇员数据数组。如果程序直接使用这个全局数据,那么这个数据结构的实现信息—— 它是一个数组且拥有最多1000个元素——将充斥着整个程序。如果这个程序只通过存取子程 序来使用这个数据结构,那么就只有这个存取子程序才知道这些细节。 交叉依赖 一个不易察觉的信息隐蔽障碍是交叉依赖。比如模块A中的某一部 分调用了模块B中的 一个子程序,而模块B中又有一部分调用了模块A中的子程序。应避免这种交叉依赖现象。 因为只有在两者都已准备好的情况下,你才能测试其中的一个。当程序被覆盖时,必须使A 和B同时驻留在内存中,才能避免系统失败。通过寻找两个模块中被其它模块使用的部分, 把这些部分放入新的模块A’和B’中,用模块A和B中的其余部分来调用A’和B’,基本上可 以消除这一问题。 误把模块数据当成全局数据 如果你是个谨慎的程序员,那么信息隐蔽的障碍之一便是误把模块数据当作全局数据而 避免使用它,因为要避免由于使用全局数据而带来的麻烦。但是,如同在6.1节“模块化: 内聚性与耦合性”中所说的那样,这对其进行存取,因而由模块数据带来的麻烦要比全局数据小得多。 如果不使用模块数据,就不会知道了解由模块所带来的巨大收益。如果一个子程序向模 块传递了只有它才能处理的数据的话,那么就不该由模块来承担拥有数据集合并对其进行操 作的罪责。比如,在前面列举的建议利用如下语句来提高抽象程度的例子中: CurrentEmployee = NextAvaliableEmployee() 或使用: CurrentEmployee=NextAvailableEmployee(EmployeeList, EmployeeID) 这两个赋值语句间的区别是:在第一种情形下, NextAvailableEmployee()拥有关于雇员表 和目前表中的入口是哪一个入口的信息,而在第二种情况下,NextAvailableEmployee (EmployeeList, EmployeeID)只是从向它传递数据的子程序中借用这些信息。当你使用 NextAvailableEmployee()时,为了提供全部的抽象能力,不必担心它所需要的数据,只要记住 它负责自己的问题就可以了。 全局数据主要会产生两个问题:(1)一个子程序在对其进行操作时并不知道其它子程序也 在对它进行操作;(2)这个子程序知道其它子程序也在对其进行操作,但不知道它们对它干了 什么。而模块数据则不会产生这些问题,因为只有被放在一个单独模块中的有限几个子程序 才被允许对模块数据进行直接存取操作,当一个子程序进行这种操作时,它知道别的子程序 也在进行同样操作,并确切知道这些是哪几个子程序。如果你还不相信的话,试一下,结果 会令你满意的。 误认为会损失性能 信息隐蔽的最后一个障碍是在结构设计和编码两个层次上,都试图避免性能损失。事实 上,在两个层次上你都不必担心这一点。在结构设计层次上,这种担心之所以不必要是因为, 以信息隐蔽为目标进行结构设计,与以性能为目标进行结构设计是不矛盾的,只要你同时考 虑到这两点,那么就可以同时达到这两个目标。更常见的担心是在编码层次上,这种担心主 要是认为间接而不是直接地存取数据结构会带来运行时间上的损失,因为这样做附加了调用 层次。当测试了系统的性能并在瓶颈问题上有所突破时,这种担心是不成熟的。为提高软件 性能做准备的最好手段之一就是模块化设计,这样,在发现了更好的方案之后,不必改变系 统其余部分,就可以对个别子程序进行优化。 6.3 建立模块的理由 即使不经常使用模块,凭直觉也很可能会对可以放入模块的数据和子程序种类有所了解。 从某种意义来说,模块并不是人们的目标,它只是数据及对数据所进行的操作的集合,并且支 持面向对象的概念描述它的这种有限的面向对象特性的词汇是Booch 1991年提出来的“基于对象”编程。 以下是一些适合使用模块的域: 用户接口。可以建立一个模块来把用户接口要素独立起来。这样,不会影响程序其它部分, 你就可以进行改进。在许多情况下,用户接口模块中往往包含有几个模块来进行诸如菜单操作、 窗口管理、系统帮助等。 对硬件有依赖的区域。把对硬件有依赖的区域放入一个或几个模块中。这些区域常见的有: 与屏幕、打印机、绘图机、磁盘驱动器、鼠标等的接口。把这些对硬件有依赖的区域独立起来 可能帮助把程序移植到新环境下运行。设计一个硬件经常变动的程序 时,这也是很有帮助的, 可以编写软件表模拟与特定硬件的交互作用,硬件不存在或不稳定时,让接口子程序与这些模 拟软件打交道。然后在硬件稳定时,再让接口子程序与硬件打交道。 输入与输出。把输入/输出封装起来,可以使程序其余部分免受经常变动的文件和报告 格式的影响。把输入/输出放入模块,也使得程序很容易适应输入/输出设备的变动。 操作系统依赖部分。把对操作系统有依赖的部分放入模块的原因与把对硬件有依赖部分放 入模块的原因是相同的。如果你正在编写一个在Microsoft Windows 下运行的软件,为什么要把 它局限于Windows环境下呢,你完全可以把对Windows的调用放在一个Windows接口模块中。 如果以后想把程序移植到Macintosh或者OS/2环境下,你所要做的只是改动一下接口模块而已。 数据管理。应把数据管理部分放入模块中,让其中的子程序去与那些杂乱的实现细节打交 道。而让模块外的子程序用抽象的方式与数据打交道,这种方式应该尽可能避免实际处理问题, 如果你认
本文档为【代码大全 java】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_191127
暂无简介~
格式:doc
大小:43KB
软件:Word
页数:0
分类:生活休闲
上传时间:2017-09-16
浏览量:30