依赖和耦合关系.pdf
《依赖和耦合关系.pdf》由会员分享,可在线阅读,更多相关《依赖和耦合关系.pdf(10页珍藏版)》请在三一文库上搜索。
1、依 赖 和 耦 合 关 系 1、依赖和耦合(Dependency and Coupling) ( 1)什么是依赖 Rose 的帮助文档上是这样定义“依赖”关系的:“依赖描述了两个模型元素之间的关系,如果被依赖 的模型元素发生变化就会影响到另一个模型元素。典型的,在类图上,依赖关系表明客户类的操作会调用 服务器类的操作。 ” ( 2)什么是耦合 Martin Fowler 在 Reducing Coupling一文中这样描述耦合:“如果改变程序的一个模块要求另一个 模块同时发生变化,就认为这两个模块发生了耦合。” Fowler 2001 注意: 从上面的定义可以看出:如果模块A 调用模块B 提供
2、的方法,或访问模块B 中的某些数据成员(当 然,在面向对象开发中一般不提倡这样做),我们就认为模块A 依赖于模块B,模块 A 和模块 B 之间发生 了耦合。 耦合是依赖的同义词,被定义为“两个元素之间的一种关系,其中一个元素变化,导致另一个元素变 化” 。抽象耦合被定义为“若类A 维护一个指向抽象类B 的引用,则称类A 抽象耦合于B” 。 2、依赖是不可避免的 ( 1) “分而治之”的问题处理方法 对于复杂的系统,我们常常采用它划分成多个模块,这样将能够有效地控制模块的复杂度,使每个模 块都易于理解和维护。 ( 2) “分而治之”的结果是产生依赖关系 一旦我们采用 “分而治之”的处理方法后,模
3、块之间就必须以某种方式交换信息,也就是必然要 发生某种耦合关系。 如果某个模块和其它模块没有任何关联(哪怕只是潜在的或隐含的依赖关系),我们就几乎可以 断定,该模块不属于此软件系统,应该从系统中剔除。 如果所有模块之间都没有任何耦合关系,其结果必然是:整个软件不过是多个互不相干的系统的 简单堆积, 对每个系统而言,所有功能还是要在一个模块中实现,这等于没有做任何模块的分解。 ( 3)依赖是不可避免的 因此,模块之间必定会有这样或那样的依赖关系,我们永远也不要幻想消除所有的依赖(耦合关系)。 我们在类的设计时,应该首先考虑的是该类应该尽可能依赖不经常变化的“目标”- 比如,系统的API 库或者框
4、架中的组件-试图令具体的、易变的模块依赖于抽象的、稳定的模块的基本原则。 在 Java 中,表示字符串的是具体内String。该类是稳定的,也就是说,它不太会改变。因此,直接依 赖于它不会造成损害。 既然变化不可避免,我们所能做的就是处理好依赖关系,将变化造成的影响的波及范围尽量减小。 ( 4)我们所追求的是尽可能降低过强的耦合关系 “依赖”是和“变化”紧密联系在一起的概念。由于依赖关系的存在,变化在某处发生时,影响会波 及开去,造成很多修改工作,这就是依赖的危害。 因为,过强的耦合关系(如一个模块的变化会造成一个或多个其他模块也同时发生变化的依赖关 系)会对软件系统的质量造成很大的危害。 特
5、别是当需求发生变化时,代码的维护成本将非常高。所以,我们必须想尽办法来控制和消解不 必要的耦合,特别是那种会导致其它模块发生不可控变化的依赖关系。 ( 5)如何达到 - 采用什么的策略或者方法 依赖倒置、控制反转、依赖注入等原则。 3、依赖倒置(DIP-Dependency Inversion Principle ) ( 1)什么是依赖倒置-将依赖关系倒置为依赖接口 依赖倒置原则就是建立在抽象接口的基础上的。Robert Martin 这样描述依赖倒置原则Martin 1996 : 上层模块不应该依赖于下层模块,它们共同依赖于一个抽象。 抽象不能依赖于具体,具体依赖于抽象- 也就是“系统的核心
6、逻辑”不依赖于“具体的实现细 节”。 依赖性倒置原则形式化了抽象耦合的概念,明确表述了应该“依赖于抽象类,不要依赖于具体类”。 ( 2)如何达到依赖倒置的效果 为了消解两个模块间的依赖关系,应该在两个模块之间定义一个抽象接口,上层模块调用抽象接口定 义的方法,下层模块实现该接口。 针对接口编程遵守上述原则,从而在很大程度上阻止了变化波及范围的扩大,有效地隔离了变化,有 助于增强系统的可重用性和可扩展性。 ( 3)为什么要依赖接口 因为抽象是相对稳定的或者是相对变化不频繁的,而具体是易变的 因此,要使我们的设计具有很大的灵活性,就需要做到大家都依赖于抽象的东西,而利用抽象隔离具 体类之间的关系,
7、这样使得“具体”的任何改动都可以在局部范围内实现,而不影响其它的结构。 比如,一个IO 系统它必然就有READ/WRITE这两个抽象,至于具体是磁盘还是键盘,那是下面的实 现不同了,通过这种构架,能保持软件的弹性与可维护性。 依赖抽象是我们实现代码扩展和运行期内绑定(多态)的基础 因为一旦类的使用者依赖某个具体的类,那么对该依赖的扩展就无从谈起;而依赖某个抽象类,则只 要实现了该抽象类的子类,都可以被类的使用者使用,从而实现了系统的扩展。 ( 4)示例(摘录网上资料) 这里举个比较好笑的例子:一个即将做领导的儿子问曾经做领导的父亲怎么才能平步青云,父亲说你 不能说假话,因为老百姓会不答应,也不
8、能说实话,因为领导会对你有意见,儿子思索良久问:那我该说 什么 ? 父亲意味深长的说:空话 笑话不但好笑,还能反映一定的道理,为啥空话这么有用,因为他是抽象的,而抽象不涉及到一些具 体的数据或者事务,因此他是稳定的,是不容易变化的,同时基本上也是正确的。 4、依据“依赖倒置原则”进行编程开发 ( 1)体现倒置原则的UML 类图 以前传统的过程设计中是从上到下的一条依赖线 现在是平的一条到接口,然后是一条从下往上的的关联线。 ( 2)其主要的优点 由于在依赖倒置中,通过抽象接口达到隔离了“服务的提供者”和“服务的请求者”,使它们之 间没有直接的耦合关系,两者可以独立地扩展或重用。 依赖倒置原则是
9、许多面向对象技术的优点的根本。合理地应用它对于建立可复用的框架是必要 的。对于构建富有变化弹力的代码也是相当重要的。而且,由于抽象和具体相互完全分离,代码 的维护就容易很多了。 依赖倒置原则一般应用于类与类之间的代码级的依赖关系。 ( 3)应用依赖倒置原则的代码示例 任何实例对象变量都不应该持有一个指向具体类的引用,而应该为接口类型的对象声明 class SomeClass private SomeInterface obj=null; 任何类都不应该从具体类派生,而应该实现某个接口-面向接口编程,而不要面向实现编程 class SomeClass implements SomeInterfa
10、ce / extends SuperClass 5、依赖倒置原则示例 (1)持久层中的各个组件常规的设计和实现方案 在很多 Web应用系统中,都需要对后台的数据库系统进行访问以实现数据存储的目的。而一个常见的 解决手段是使用分层的设计思想和方法,将Web应用系统中的持久层中的各个组件分为数据访问操作组件 (DAO ,Data Access Object)和数据连接组件,下面的图中所示为这种常规的设计和实现方案的类图。 (2)常规设计和实现方案中所反映出的问题 从上面的图中的所示的数据访问操作组件和数据连接组件之间的关系来看,两者产生了紧密的藕合关 系。一旦数据连接组件有了任何变化,数据访问操作
11、组件都有可能会受其影响而需要被改动。 当然,如果只是针对这两个类本身而言的话,这种依赖关系根本算不上什么问题。然而,在一个实际 的应用系统中,数据访问操作组件和数据连接组件都会由不只一个类而构成的,并都有一定的技术实现上 的复杂度,这时它们两者之间的这种依赖关系就会增加系统的复杂性;而且随着应用系统中的各个程序模 块越来越多、 功能实现也越来越复杂时,这种由于两者之间的紧密藕合所带来的系统的复杂度会越来越高。 因此,如果不限制它们之间的紧密藕合联系,那模块间的依赖、程序的复杂度和开发维护的难度都会成指 数上升。 (3)对设计进行优化在两者之间添加一个抽象的接口 在两者之间添加一个数据连接组件的
12、接口,并在其中包含数据访问操作组件中所需要的各种数据连接 的服务方法的定义,而某个具体的数据连接组件则实现这个接口。此时数据访问操作组件则只需要调用数 据连接组件接口中的服务来实现数据库的各种连接功能,两者都只依赖于数据连接组件的接口。请见下面 的图中所示的优化设计结果的类图。 这样, 数据访问操作组件到数据连接组件的依赖关系被数据连接组件的接口所隔离开。因为在接口中 只包含了所需要的各种连接的服务功能的定义,而不包括任何连接的服务功能的具体实现,所以数据连接 组件的接口的内容在具体设计时也会很简单。在数据连接组件接口不变的情况下,数据访问操作组件和某 个具体的数据连接组件这两个模块都可以自由
13、地进行修改而不影响到对方(比如添加另一个数据连接组 件),依赖关系也变得简单和可管理。 (4)进一步改进本设计和实现方案核心逻辑不依赖于具体的实现细节 如果从系统架构的角度来看上面的图中所示的设计和实现方案还存在一定的问题,因为数据访问操作 组件所提供的功能是整个应用系统的数据访问的核心部分,而数据连接组件中的各个功能方法则可以看成 是具体实现的的细节。因此,从这个角度来看图中优化设计后的结果时,该设计是“核心逻辑依赖于具体 的实现细节”。当然,也就没有遵守依赖倒置原则中的“抽象不能依赖于具体,具体依赖于抽象”的要求。 因为, 当细节变化(数据连接中的数据源或者连接方式发生变化)时,数据访问操
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 依赖 耦合 关系
链接地址:https://www.31doc.com/p-5057326.html