《代码大全》学习笔记(6):模块化设计

        子程序是具有一定功能的,可以调用的函数或过程;而模块则是指数据及作用于数据的子程序的集合。
6.1 模块化:内聚性与耦合性
      “模块化”同时涉及到子程序设计和模块设计;模块化设计的目标是使每个子程序都成为一个“黑盒子”;使用单独一个子程序是很难达到这一目的的,这也正是引入模块的原因。
6.1.1 模块内聚性
        模块的内聚性准则,与单个子程序的内聚性准则一样,都是十分简单的;一个模块应该提供一组相互联系的服务。
6.1.2 模块耦合
        模块与程序其它部分间的耦合标准与子程序间的耦合标准也是类似的;模块应被设计成可以提供一整套功能,以便程序的其它部分与它清楚地相互作用。
        如果模块所提供的功能是不完善的,其它子程序可能被迫对其内部数据进行读写操作。
        为了设计出强内聚而又松散耦合的模块,必须在设计模块和设计单个子程序的标准之间进行平衡与折衷;降低子程序之间耦合性的重要措施之一,就是尽可能减少使用全局变量。
        从所有模块中的子程序可以对它进行存取的角度来说,模块中数据很像是全局数据。

6.2 信息隐蔽
        进行信息隐蔽的设计思想贯穿了软件开发的每一个层次,从使用命名的常量而不是使用自由常量到子程序设计、模块设计和整个程序设计。
6.2.1 保密
        信息隐蔽中的关键概念是“保密”,每一个模块的最大特点都是通过设计和实现,使它对其它模块保密;模块的作用是将自己的信息隐蔽起来以保卫自己的隐私权;信息隐蔽的另一个称谓是“封装”,其意思是一个外表与内容不一样的盒子。
        模块的接口应该尽可能少地暴露它的内部内容。
6.2.2 信息隐蔽举例
        除了方便修改,隐含复杂数据结构细节的另一个重要原因是:隐含细节可以澄清你编写某段代码的意图。
        隐含数据结构的最后一个原因是出于对可靠性的考虑。
        隐含数据结构细节的另一个好处是容易调试。
        应用存取子程序最后一个优点是,可以使所有对数据的存取所遵循的是一种平行的组织形式;或者通过存取子程序、或者直接对数据进行存取,不会两者兼而有之。
6.2.3 常见需要隐含的信息
        容易被改动的区域:在为应付改动的工作中要遵循的步骤:1)识别出那些可能被改动的地方;2)把可能被改动的地方分离出来;一些可能变动的区域:1)对硬件有依赖的地方;2)输入和输出;3)非标准语言特性;4)难于设计和实现的域;5)状态变量;6)数据规模限制;7)商业规则;8)预防到改动。
        复杂的数据:所有的复杂数据都很可能被改动;如果它很复杂而对它使用得又很多,那么在实现层次上与其打过交道后,可能会发现实现它的更好方式;对复杂数据的使用程度,主要取决于程序。
        复杂的逻辑:隐含复杂的逻辑可以改善程序的可读性。
        在程序语言层次上的操作:一般来说,在设计一组在程序语言语句层次上操作数据的子程序时,应该把对数据操作隐含在子程序组中,这样程序的其余部分就可能在比较抽象的层次上处理问题了。
6.2.4 信息隐蔽的障碍
        信息过度分散:信息隐蔽的一个常见障碍是系统中信息过于分散;另一个信息过于分散的例子是程序中分布着与用户交互的接口;而还有一个例子则是全局数据结构。
        交叉依赖:一个不易察觉的信息隐蔽障碍是交叉依赖。
        误把模块数据当成全局数据:全局数据主要会产生两个问题:1)一个子程序在对其进行操作时并不知道其它子程序也在对它进行操作;2)这个子程序知道其它子程序也在对其进行操作,但不知道它们对它干了什么。
        误认为会损失性能:信息隐蔽的最后一个障碍是在结构设计和编码两个层次上,都试图避免性能损失。

6.3 建立模块的理由
        一些适合使用模块的域:1)用户接口;2)对硬件有依赖的区域;3)输入与输出;4)操作系统依赖部分;5)数据管理;6)真实目标与抽象数据类型;7)可再使用的代码;8)可能发生变动的相互联系的操作;9)互相联系的操作。

6.4 任何语言中实现模块
6.4.1 模块化所需的语言支持
        模块包括数据、数据类型、数据操作以及公共和局部操作的区分等。
        数据需要在三个层次上可以被存取和隐含:在局部,在模块中及在全局中;绝大多数语言都支持局部数据和全局数据。
        对于数据类型的可存取性和可隐含性的要求,与对数据的要求是类似的。
        对模块层次上的子程序的要求也与上述相类似。
6.4.2 语言支持概述
6.4.3 伪模块化
        把数据和子程序装入模块;保证模块的内部子程序是专用的;通过在说明的地方加注释来明确区分公用和专用子程序;不允许子程序调用其它模块的内部子程序;采用命名约定来表明一个子程序是内部的还是外部的;采用表明它是内部的还是外部的命名规定;保证子程序的内部数据是专用的。
6.4.4 检查表
      模块的质量。

6.5 小结

(1) 不管调用哪一个,子程序与模块的不同是很重要的,要认真考虑子程序与模块的设计。
(2) 从模块数据是被几个子程序使用的这一角度来说,它与全局数据是相同的,但从可以使用它的子程序是有限的,而且清楚地知道是哪些子程序可以使用它这一角度来说,模块数据与全局数据又是不同的;因此,可以使用模块数据而没有全局数据的危险。

(3) 信息隐蔽总是有益的,其结果是可以产生可靠的易于改进的系统,它也是目前流行的设计方法的核心。
(4) 创建模块的原因有许多是与创建子程序相同的,但模块概念的意义要比子程序深远得多,因为它可以提供一整套而不是单独一个功能,因此,它是比子程序更高层次的设计工具。

(5) 可以在任何语言中进行模块设计,如果所采用的语言不直接支持模块,可以用编程约定对其加以扩展,以达到某种程度的模块化。

 

       本章小结:

       本章介绍了模块化设计,与上一章的子程序相对应。

        在实际的项目中,模块化的方法用得非常多。每一个开发人员所做的工作,其实就是完成了自己负责的一个模块。在开发工作完成之后,需要进行集成测试,也就是验证模块之间能否协同工作。

时间: 2024-11-03 23:27:55

《代码大全》学习笔记(6):模块化设计的相关文章

thinkphp学习笔记5—模块化设计

原文:thinkphp学习笔记5-模块化设计 1.模块结构 完整的ThinkPHP用用围绕模块/控制器/操作设计,并支持多个入口文件盒多级控制.ThinkPHP默认PATHINFO模式,如下: http://serverName/index.php(或者其他应用入口文件)/模块/控制器/操作/[参数名/参数值...] 应用:由同一个入口文件访问的项目称为一个应用,在完整版的代码中就是Application 模块:一个应用下面可以包含多个模块,每个模块对应独立的目录,在完整版的代码中有Admin,

TheBeerHouse网站项目学习笔记(5)---架构设计

摘要:TheBeerHouse整个网站是属于CMS(Content Management System)架构的系统,即基于内容的网站 设计,这是网站设计最普遍的一种架构.在此网站的设计中,为什么需要用到许多抽象基类,为什么需要各种 看似让人难以理解的属性和成员变量,设计意图是什么,这么设计有什么好处等等这类问题,都是值得我 们思考和探讨的问题.我们将从层次关系.类图关系.设计意图这几个方面讨论上述提出的问题. 一. 层次关系 如上图,红色虚线框内的将是我们讨论的内容,这里面几乎全部是类,他们共同

PHP学习笔记之面向对象设计

  面向对象设计是php程序开发中一个很重要的内容块,如果你想成为高级php程序员我们必须知道面向对象设计具体用法与写法. 维护简单 模块化是面向对象编程中的一个特征.实体被表示为类和同一名字空间中具有相同功能的类,我们可以在名字空间中添加一个类而不会影响该名字空间的其他成员. 可扩充性 面向对象编程从本质上支持扩充性.如果有一个具有某种功能的类,就可以很快地扩充这个类,创建一个具有扩充的功能的类. 代码重用 由于功能是被封装在类中的,并且类是作为一个独立实体而存在的,提供一个类库就非常简单了.

javascript常用的代码片段(学习笔记)

获取DOM对象    代码如下 复制代码 function getel(e) {     if (document.getElementById) {         return document.getElementById(e);     } else if (document.all){         return document.all[e];     } } xmlHttp  代码如下 复制代码 //定义方法 获取XMLHttpRequest对象 function ajaxLoa

php编程代码规范学习笔记(适合初学者)(1/2)

命名规范 Θ 类文件都以.class.php为后缀,使用驼峰法命名,并且首字母大写,例如 Pay.class.php; Θ 类名和目录_文件名一致.例如:类名Zend_Autoloader的目录是Zend/Autoloader.class.php; Θ 函数的命名使用小写字母和下划线的方式.例如:get_client_ip; Θ 方法的命名使用驼峰法,首字母小写或者使用下划线"_",例如listComment(),_getResource(),通常下划线开头的方法属于私有方法; Θ 属

TEX学习笔记

整理在这里, 方便以后容易查找. 毕竟每个tex的模板有些不一样.   Beamer: Latex beamer 学习总结 http://blog.sina.com.cn/s/blog_6cf921f30101aq0g.html  Beamer 主题选择: http://deic.uab.es/~iblanes/beamer_gallery/       https://latex.simon04.net/   Tex arrows: http://www.sascha-frank.com/Ar

《代码大全》学习笔记(1):欢迎进入软件创建世界

写在前面:          它山之石,可以攻玉!        <代码大全>是编程领域里的一本经典书籍,全书介绍了基本数据类型.变量命名.子程序和函数的编写.编程工具以及调试等内容.全书内容翔实.实用性强,特别适合刚入门或即将入门的程序员学习.该书对于良好编程习惯的养成具有极大的促进作用!         本系列文章是我在阅读<代码大全>过程中的学习笔记,基本上是按照原书的章节顺序进行编排的.在每一章的最后还有个人学习小结,供大家参考.希望大家能够从这本经典的书籍中受益,写出高质

《代码大全》学习笔记(5):高质量子程序特点

        什么叫"子程序"?子程序是具有单一功能的可调用的函数或过程.5.1 生成子程序的原因        降低复杂性:使用子程序的最首要原因是为了降低程序的复杂性,可以使用子程序来隐含信息,从而使你不必再考虑这些信息:一个子程序需要从另一个子程序中脱离出来的原因之一是,过多重数的内部循环和条件判断.         限制了改动带来的影响:由于在独立区域进行改动,因此,由此带来的影响也只限于一个或最多几个区域中.         隐含顺序:把处理事件的非特定顺序隐含起来.   

JavaScript权威设计--JavaScript函数(简要学习笔记十)

1.函数命名规范 函数命名通常以动词为前缀的词组.通常第一个字符小写.当包含多个单词时,一种约定是将单词以下划线分割,就像"like_Zqz()". 还有一种就是"likeZqz()".有些些函数是用作内部用的或者为私有函数通常以一条下划线为前缀,就像"_zqzName()".   2.以表达式方式定义的函数 如: var zqz=function (){ return "zhaoqize"; } 在使用的时候必须把它赋值给一