转自:http://www.cnblogs.com/tiwlin/archive/2010/02/24/1672459.html

s1. 低耦合(low coupling)

“低耦合”这个词相信大家已经耳熟能详,我们在看spring的书籍、mvc的数据、设计模 式的书籍,无处不提到“低耦合、高内聚”,它已经成为软件设计质量的标准之一。那么什么是低耦合?耦合就是对某元素与其它元素之间的连接、感知和依赖的量 度。这里所说的元素,即可以是功能、对象(类),也可以指系统、子系统、模块。假如一个元素a去连接元素b,或者通过自己的方法可以感知b,或者当b不存 在的时候就不能正常工作,那么就说元素a与元素b耦合。耦合带来的问题是,当元素b发生变更或不存在时,都将影响元素a的正常工作,影响系统的可维护性和 易变更性。同时元素a只能工作于元素b存在的环境中,这也降低了元素a的可复用性。正因为耦合的种种弊端,我们在软件设计的时候努力追求“低耦合”。低耦 合就是要求在我们的软件系统中,某元素不要过度依赖于其它元素。请注意这里的“过度”二字。系统中低耦合不能过度,比如说我们设计一个类可以不与jdk耦 合,这可能吗?除非你不是设计的java程序。再比如我设计了一个类,它不与我的系统中的任何类发生耦合。如果有这样一个类,那么它必然是低内聚(关于内 聚的问题我随后讨论)。耦合与内聚常常是一个矛盾的两个方面。最佳的方案就是寻找一个合适的中间点。

哪些是耦合呢?

1.元素b是元素a的属性,或者元素a引用了元素b的实例(这包括元素a调用的某个方法,其参数中包含元素b)。

2.元素a调用了元素b的方法。

3.元素a直接或间接成为元素b的子类。

4.元素a是接口b的实现。

幸运的是,目前已经有大量的框架帮助我们降低我们系统的耦合度。比如,使用struts我们 可以应用mvc模型,使页面展现与业务逻辑分离,做到了页面展现与业务逻辑的低耦合。当我们的页面展现需要变更时,我们只需要修改我们的页面,而不影响我 们的业务逻辑;同样,我们的业务逻辑需要变更的时候,我们只需要修改我们的java程序,与我们的页面无关。使用spring我们运用ioc(反向控 制),降低了业务逻辑中各个类的相互依赖。假如类a因为需要功能f而调用类b,在通常的情况下类a需要引用类b,因而类a就依赖于类b了,也就是说当类b 不存在的时候类a就无法使用了。使用了ioc,类a调用的仅仅是实现了功能f的接口的某个类,这个类可能是类b,也可能是另一个类c,由spring的配 置文件来决定。这样,类a就不再依赖于类b了,耦合度降低,重用性提高了。使用hibernate则是使我们的业务逻辑与数据持久化分离,也就是与将数据 存储到数据库的操作分离。我们在业务逻辑中只需要将数据放到值对象中,然后交给hibernate,或者从hibernate那里得到值对象。至于用 oracle、mysql还是sql server,如何执行的操作,与我无关。

但是,作为优秀的开发人员,仅仅依靠框架提供的降低软件耦合的方法是远远不够的。根据我的经验,以下一些问题我们应当引起注意:

1) 根据可能的变化设计软件

我们采用职责驱动设计,设计中尽力做到“低耦合、高内聚”的一个非常重要的前提是,我们的软 件是在不断变化的。如果没有变化我们当然就不用这么费劲了;但是如果有变化,我们希望通过以上的设计,使我们在适应或者更改这样的变化的时候,付出更小的 代价。这里提供了一个非常重要的信息是,我们努力降低耦合的是那些可能发生变更的地方,因为降低耦合是有代价的,是以增加资源耗费和代码复杂度为代价的。 如果系统中某些元素不太可能变更,或者降低耦合所付出的代价太大,我们当然就应当选择耦合。有一次我试图将我的表现层不依赖于struts,但发现这样的 尝试代价太大而失去意义了。对于软件可能变更的部分,我们应当努力去降低耦合,这就给我们提出一个要求是,在软件设计的时候可以预判日后的变化。根据以往 的经验我认为,一个软件的业务逻辑和采用的技术框架往往是容易变化的2个方面。客户需求变更是我们软件设计必须考虑的问题。在rup的开发过程中,为什么 需要将分析设计的过程分为分析模型和设计模型,愚以为,从分析模型到设计模型的过程实际上是系统从满足直接的客户需求到优化系统结构、适应可预见的客户需 求变更的一个过程。这种客户需求的变更不仅仅指对一个客户需求的变更,更是指我们的软件从适应一个客户需求到适应更多客户需求的过程。另一个方面,现在技 术变更之快,ejb、hibernate、spring、ajax,一个一个的技术像走马灯一样从我们脑海中滑过,我们真不知道明天我在用什么。在这样的 情况下,适应变化就是我们最佳的选择。

2) 合理的职责划分

合理的职责划分,让系统中的对象各司其职,不仅是提高内聚的要求,同时也可以有效地降低耦 合。比如评审计划bus、评审表bus、评审报告bus都需要通过评审计划dao去查询一些评审计划的数据,如果它们都去直接调用评审计划dao(如图 a),则评审计划bus、评审表bus、评审报告bus三个对象都与评审计划dao耦合,评审计划dao一旦变更将与这三个对象都有关。在这个实例中,实 际上评审计划bus是信息专家(关于信息专家模式我将在后面讨论),评审表bus和评审报告bus如果需要获得评审计划的数据,应当向评审计划bus提出 需求,由评审计划bus提供数据(如图b)。经过这样的调整,系统的耦合度就降低了。

3) 使用接口而不是继承

通过对耦合的分析,我们不难发现,继承就是一种耦合。如果子类a继承了父类b,不论是直接或 间接的继承,子类a都必将依赖父类b。子类a必须使用在存在父类b的环境中,父类b不存在子类a就不能使用,这样将影响子类a的可移植性。一旦父类b发生 任何变更,更改或去掉一个函数名,或者改变一个函数的参数,都将导致子类a不得不变更,甚至重写。假如父类b的子类数十上百个,甚至贯穿这个项目各个模 块,这样的变更是灾难性的。这种情况最典型的例子是我们现在使用hibernate和spring设计dao对象的方式,具体的描述参见我写的《如何在 struts + spring + hibernate的框架下构建低耦合高内聚的软件结构》一文。

总之,“低耦合”给软件项目带来的优点是:易于变更、易于重用。

转自:http://www.cnblogs.com/tiwlin/archive/2010/02/24/1672459.html(原题有修改)

======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/

Jeffery C. Hill相关推荐

  1. C++希尔密码Hill Cipher算法(附完整源码)

    希尔密码Hill Cipher的算法 希尔密码(Hill Cipher) 的算法的完整源码(定义,实现,main函数测试) 希尔密码(Hill Cipher) 的算法的完整源码(定义,实现,main函 ...

  2. Hill加密算法(matlab 实现)

    文章目录 一.主要函数解析 二.注意事项 三.演示图 四.问题 五.代码 一.主要函数解析 1.function [ret] = Hill(M,Str) M为密钥矩阵 Str为待转换数组 二.注意事项 ...

  3. 08:vigenère密码_密码技术:Vigenére密码,Playfair密码,Hill密码

    08:vigenère密码 1)Vigenére密码 (1) Vigenére Cipher) This technique is an example of Polyalphabetic Subst ...

  4. hill密码源代码c语言,古典密码(Hill加密算法)(示例代码)

    "Hill的加密与解密" Hill加密是另一种多字母代替密码,与多表代替密码不同的是,Hill密码要求将明文分成同等规模的若干个分组(最后一个分组涉及到填充),每一个分组被整体的加 ...

  5. Python:实现hill climbing爬山法用来寻找函数的最大值算法(附完整源码)

    Python:实现hill climbing爬山法用来寻找函数的最大值算法 import mathclass SearchProblem:def __init__(self, x: int, y: i ...

  6. C++实现Hill算法(希尔算法)

    文章目录 算法简介 代码 算法简介 Hill算法是一种多表代替密码,由数学家Lester Hill在1929年发明,其加密算法为:C = E(K, P) = PK mod 26,解密算法为:P = D ...

  7. 致力于推动植物性食品革命的可持续性食品科技公司——BENSON HILL将与STAR PEAK CORP II合并

    Benson Hill, Inc.将与Star Peak Corp II合并上市(纽交所:STPC). 交易概览 完成交易后,以Star Peak普通股每股10.00美元的价格计算,假设Star Pe ...

  8. 传统加密技术续-Hill Vigenere Vernam

    在上篇文章中,讲述了一些加密解密的概念以及Caesar.单表替换密码.Playfair密码.在这篇文章中主要涉及Hill密码,Vigenere密码,Vernam密码,置换技术. Hill密码 希尔密码 ...

  9. [Introduction to AI] Local Search::Hill Climbing (最陡上升)

    本文为 BJUT 2021 Fall Introduction to AI 的读书笔记: 课程教材为:Artificial Intelligence: A Modern Approach: Cover ...

  10. [C] Indian Hill C Style(印第安山风格指南)

    C语言的印第安山风格及编码标准 贝尔实验室 Henry Spencer [说明]:英语四级略过的水平的翻译,希望在令人捉急的英语阅读水平上进步.在此路懒跑的同时也会不禁地惭愧着.<Indian ...

最新文章

  1. 英国更注重人工智能基础性研究
  2. 网摘精灵教程:网摘自动提交工具。
  3. sql server 查看磁盘可用空间
  4. Sphinx的介绍和原理探索
  5. SQL Server 日志清理、数据文件收缩
  6. android xml左边,Android XML – 如何将项目对齐到最左侧,中间和最右侧
  7. DNT 3.1 快速安装手记
  8. java毕业设计户籍管理系统(附源码、数据库)
  9. 低温和大风会增加心梗风险
  10. 客户关系管理系统(CRM)的开发过程中使用到的开发工具总结
  11. 翡翠手链的寓意是什么?要如何保养它才好!
  12. 本周内外盘行情回顾2022.2.27
  13. 《2020年全球程序员收入报告》,看完报告我酸了!
  14. 使用stata临床决策曲线进行外部模型验证
  15. swift之mutating关键字
  16. Java学习笔记(二):Java程序基础
  17. 灰色预测模型--两秒直接上手
  18. 解决“此图片来自微信公众平台 未经允许不可引用”的方法
  19. java哨片红盒 绿盒的区别_海淘维骨力怎么区分红盒,绿盒,蓝盒版本之间的区别...
  20. SSM+传统民间工艺线上商城 毕业设计-附源码181701

热门文章

  1. 网易考拉布局和css样式
  2. arcgis for js4.x自定义图例位置添加到地图并导出
  3. 将一个文件夹下的MP4文件合并为一个
  4. 大宗商品交易平台:解决期货的最后“一公里”
  5. Unity3D手游开发实践《腾讯桌球》客户端开发经验总结
  6. Python3快速入门—5.函数
  7. java 将服务器的图片打包下载成.zip ,通过浏览器下载。
  8. Guawa的Splitter的工具类
  9. potplayer最佳设置_potplayer最佳设置
  10. 【数据可视化工具DataEase】安装时提示 “Pool overlaps with other one on this address space“