版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、- 我个人对编程开发的总结面向对象开发,一切皆对象方法函数应该提炼出来,代码服用使用工厂模式便于管理维护面向接口开发 方法不要随便public分层开发 公用的方法 提炼出来业务逻辑和显示应该分离-下面是一篇网上的好文章首先要知道一个软件是由多个子程序组装而成,而一个程序由多个模块(方法)构成!而内聚就是指程序内的各个模块之间的关系紧密程度,偶合就是各个外部程序(子程序)之间的关系紧密程度.所以很易明白,为什么要高内聚?模块之间的关系越紧密,出错就越少!低偶合?子程序间的关系越复杂,就会产生更多的意想不到的错误!会给以后的维护工作带来很多麻烦!一个优秀软件开发人员的必修课:高内聚高内聚 Java
2、 软件工程软件模式 一个重要的模式:高内聚。2. 高内聚(High Cohesion)高 内聚是另一个普遍用来评判软件设计质量的标准。内聚,更为专业的说法叫功能内聚,是对软件系统中元素职责相关性和集中度的度量。如果元素具有高度相关的职 责,除了这些职责内的任务,没有其它过多的工作,那么该元素就具有高内聚性,反之则为低内聚性。高内聚要求软件系统中的各个元素具有较高的协作性,因为在 我们在完成软件需求中的一个功能,可能需要做各种事情,但是具有高内聚性的一个元素,只完成它职责内的事情,而把那些不在它职责内的事情拿去请求别人来完 成。这就好像,如果我是一个项目经理,我的职责是监控和协调我的项目各个阶段
3、的工作。当我的项目进入需求分析阶段,我会请求需求分析员来完成;当我的项目 进入开发阶段,我会请求软件开发人员来完成;当我的项目需要测试的时候,我会请求测试人员。如果我参与了开发,我就不是一个高内聚的元素,因为 开发不是我的职责。我们的项目为什么要高内聚呢?我觉得可以从可读性、复用性、可维护性和易变更性四个方面来理解。1可读性一 个人写文章、讲事情,条理清晰才能易于理解,这同样发生在读写软件代码上。如果一堆代码写得一团乱麻,东一个跳转西一个调用,读它的人会感觉非常头疼。这 种事情也许一直在写程序的你我都曾经有过经历。如果一段程序条理非常清晰,每个类通过名称或说明都能清楚明白它的意义,类的每个属性
4、、函数也都是易于理解 的它所应当完成的任务和行为,这段程序的可读性必然提高。在软件产业越来越密集,软件产业中开发人员协作越来越紧密、分工越来越细的今天,软件可读性的要 求相信也越来越为人们所重视。2复用性在软件开发中,最低等级的复用是代码拷贝,然后是函数的复用、对象的复用、组件 的复用。软件开发中最懒的人是最聪明的人,他们总是想到复用。在代码编写的时候突然发现某个功能是曾经实现过的功能,直接把它拷贝过来就ok了。如果这段 代码在同一个对象中,那么就提出来写一个函数到处调用就行了。如果不是在同一个对象中呢,就将其抽象成一个对象到处调用吧。如果不在一个项目中呢,那就做 成组件给各个项目引用吧。代码
5、复用也使我们的代码在复用的过程中不断精化、不断健壮、提高代码质量。代码的复用的确给我们的开发带来了不少便利,但是一段 代码能否在各个需要的地方都能复用呢?这给我们的软件开发质量提出了新的要求:好的代码可以复用,不好的则不行。软件中的一个对象如果能保证能完成自己职 能范围内的各项任务,同时又不去理会与自己职能无关的其它任务,那么它就能够保证功能的相对独立性,也就可以脱离自己所处的环境而复用到其它环境中,这是 一个具有内聚性的对象。3可维护性和易变更性在前面如何在struts+spring+hibernate的框架下 构建低耦合高内聚的软件中我提到,我们现在的软件是在不断变更的,这种变更不仅来自于
6、我们的客户,更来自于我们的市场。如果我们的软件通过变更能及时适 应我们的市场需求,我们就可以在市场竞争中获胜。如何能及时变更以适应我们的市场呢,就是通过调整软件的结构,使我们每次的变更付出的代价最小,耗费的人 力最小,这种变更才最快最经济。高内聚的软件,每个系统、模块、类的任务都高度相关,就使每一次的变更涉及的范围缩小到最小。比如评审表发生了变更,只会 与评审表对象有关,我们不会去更改其它的对象。如果我们能做到这一点,我们的系统当然是可维护性好、易变更性好的系统。那么,我们如何做 到高内聚呢?就拿前面我提到的评审项目举例。我现在要为“评审表”对象编写一段填写并保存评审表的代码。评审表对象的职责
7、是更新和查询评审表的数据,但是 在显示一个要填写的评审表的时候,我需要显示该评审计划的名称、该评审计划有哪些评审对象需要评审。现在我如何编写显示一个要填写的评审表的代码?我在评 审表对象的这个相应的函数中编写一段查询评审计划和评审对象的代码吗?假如你这样做了,你的代码就不是高内聚的,因为查询评审计划和评审对象的数据不是它 的职责。正确的方法应当去请求“评审计划”对象和“评审对象”对象来完成这些工作,而“评审表”对象只是获取其结果。另外,如果一个对象 要完成一个虽然在自己职责范围内,但过程非常复杂的任务时,也应当将该任务分解成数个功能相对独立的子函数来完成。我曾经看见一个朋友写的数百行的一个函
8、数,让人读起来非常费劲。同时这样的函数中一些相对独立的代码,本可以复用到其它代码中,也变成了不可能。所以我给大家的建议是,不要写太长的函数,超过 一百行就可以考虑将一些功能分解出去。与“低耦合”一样,高内聚也不是一个绝对,而是一个相对的指标,应当适当而不能过度。正如我们在现 实生活中,如果在一个十来人的小公司,每个人的分工可能会粗一些,所分配的职责会广一些杂一些,因为其总体的任务少;而如果在一个一两百人的大公司,每个 人的分工会细一些,所分配的任务会更加专一些,因为总体任务多,更需要专业化的分工来提高效率。软件开发也是一样,如果“评审计划”对象完成的业务功能 少,并且不复杂,它完全可以代理它的
9、子表“评审对象”和“评审者”的管理。但是“评审计划”对象需要完成的“对评审计划表的管理”这个基本职责包含的业务 功能繁多或者复杂,它就应当将“对评审对象表的管理”交给“评审对象”对象,将“对评审者表的管理”交给“评审者”对象。同样,高内聚的可维护性好、易变 更性好只能是一个相对的指标。如果一个变更的确是大范围的变更,你永远不可能通过内聚就不进行大范围的变更了。同时内聚也是要付出代价的,所以你也不必要 去为了一个不太可能的变更去进行过度设计,应当掌握一个度。过度的内聚必将增加系统中元素之间的依赖,提高耦合度。所以“高内聚”与“低耦合”是矛盾的, 必须权衡利弊,综合地去处理。在李洋等人翻译的UML
10、和模式应用中,将内聚和耦合翻译为软件工程中的阴与阳,是中国人对内聚和耦合的最佳解释。综上所述,“高内聚”给软件项目带来的优点是:可读性强、易维护和变更、支持低耦合、移植和重用性强。一个优秀软件开发人员的必修课:GRASP(2)低耦合关键字: 设计模式 我 偶然在google或yahoo这样的搜索引擎搜索GRASP发现,除了国外的网站,国内网站多介绍和讨论GoF而很少介绍GRASP,即使这少量的文章 也讲解非常粗略。个人认为作为优秀的开发人员,理解GRASP比GoF更重要,故写此文章。前面我在(原创)一个优秀软件开发人员的必修课:GRASP 软件开发模式浅析中介绍了使用GRASP的目的,今天允许
11、我调换一下顺序,先从低耦合讲起,因为诸如创建者模式、信息专家模式的根本目的就是降低耦合。1. 低耦合(Low Coupling)“低 耦合”这个词相信大家已经耳熟能详,我们在看spring的书籍、MVC的数据、设计模式的书籍,无处不提到“低耦合、高内聚”,它已经成为软件设计质量 的标准之一。那么什么是低耦合?耦合就是对某元素与其它元素之间的连接、感知和依赖的量度。这里所说的元素,即可以是功能、对象(类),也可以指系统、子 系统、模块。假如一个元素A去连接元素B,或者通过自己的方法可以感知B,或者当B不存在的时候就不能正常工作,那么就说元素A与元素B耦合。耦合带来的 问题是,当元素B发生变更或不
12、存在时,都将影响元素A的正常工作,影响系统的可维护性和易变更性。同时元素A只能工作于元素B存在的环境中,这也降低了元 素A的可复用性。正因为耦合的种种弊端,我们在软件设计的时候努力追求“低耦合”。低耦合就是要求在我们的软件系统中,某元素不要过度依赖于其它元素。请 注意这里的“过度”二字。系统中低耦合不能过度,比如说我们设计一个类可以不与JDK耦合,这可能吗?除非你不是设计的Java程序。再比如我设计了一个 类,它不与我的系统中的任何类发生耦合。如果有这样一个类,那么它必然是低内聚(关于内聚的问题我随后讨论)。耦合与内聚常常是一个矛盾的两个方面。最佳 的方案就是寻找一个合适的中间点。哪些是耦合呢
13、?1元素B是元素A的属性,或者元素A引用了元素B的实例(这包括元素A调用的某个方法,其参数中包含元素B)。2元素A调用了元素B的方法。3元素A直接或间接成为元素B的子类。4元素A是接口B的实现。幸 运的是,目前已经有大量的框架帮助我们降低我们系统的耦合度。比如,使用struts我们可以应用MVC模型,使页面展现与业务逻辑分离,做到了页面展现 与业务逻辑的低耦合。当我们的页面展现需要变更时,我们只需要修改我们的页面,而不影响我们的业务逻辑;同样,我们的业务逻辑需要变更的时候,我们只需要 修改我们的java程序,与我们的页面无关。使用spring我们运用IoC(反向控制),降低了业务逻辑中各个类的
14、相互依赖。假如类A因为需要功能F而 调用类B,在通常的情况下类A需要引用类B,因而类A就依赖于类B了,也就是说当类B不存在的时候类A就无法使用了。使用了IoC,类A调用的仅仅是实现 了功能F的接口的某个类,这个类可能是类B,也可能是另一个类C,由spring的配置文件来决定。这样,类A就不再依赖于类B了,耦合度降低,重用性提 高了。使用hibernate则是使我们的业务逻辑与数据持久化分离,也就是与将数据存储到数据库的操作分离。我们在业务逻辑中只需要将数据放到值对象 中,然后交给hibernate,或者从hibernate那里得到值对象。至于用Oracle、MySQL还是SQL Server,
15、如何执行的操作,与我无关。但是,作为优秀的开发人员,仅仅依靠框架提供的降低软件耦合的方法是远远不够的。根据我的经验,以下一些问题我们应当引起注意:1) 根据可能的变化设计软件我 们采用职责驱动设计,设计中尽力做到“低耦合、高内聚”的一个非常重要的前提是,我们的软件是在不断变化的。如果没有变化我们当然就不用这么费劲了;但是 如果有变化,我们希望通过以上的设计,使我们在适应或者更改这样的变化的时候,付出更小的代价。这里提供了一个非常重要的信息是,我们努力降低耦合的是那 些可能发生变更的地方,因为降低耦合是有代价的,是以增加资源耗费和代码复杂度为代价的。如果系统中某些元素不太可能变更,或者降低耦合所
16、付出的代价太 大,我们当然就应当选择耦合。有一次我试图将我的表现层不依赖于struts,但发现这样的尝试代价太大而失去意义了。对于软件可能变更的部分,我们应当 努力去降低耦合,这就给我们提出一个要求是,在软件设计的时候可以预判日后的变化。根据以往的经验我认为,一个软件的业务逻辑和采用的技术框架往往是容易 变化的2个方面。客户需求变更是我们软件设计必须考虑的问题。在RUP的开发过程中,为什么需要将分析设计的过程分为分析模型和设计模型,愚以为,从分析 模型到设计模型的过程实际上是系统从满足直接的客户需求到优化系统结构、适应可预见的客户需求变更的一个过程。这种客户需求的变更不仅仅指对一个客户需求 的
17、变更,更是指我们的软件从适应一个客户需求到适应更多客户需求的过程。另一个方面,现在技术变更之快,EJB、hibernate、spring、 ajax,一个一个的技术像走马灯一样从我们脑海中滑过,我们真不知道明天我在用什么。在这样的情况下,适应变化就是我们最佳的选择。2) 合理的职责划分合 理的职责划分,让系统中的对象各司其职,不仅是提高内聚的要求,同时也可以有效地降低耦合。比如评审计划BUS、评审表BUS、评审报告BUS都需要通过 评审计划DAO去查询一些评审计划的数据,如果它们都去直接调用评审计划DAO(如图A),则评审计划BUS、评审表BUS、评审报告BUS三个对象都与 评审计划DAO耦合
18、,评审计划DAO一旦变更将与这三个对象都有关。在这个实例中,实际上评审计划BUS是信息专家(关于信息专家模式我将在后面讨论), 评审表BUS和评审报告BUS如果需要获得评审计划的数据,应当向评审计划BUS提出需求,由评审计划BUS提供数据(如图B)。经过这样的调整,系统的 耦合度就降低了。3) 使用接口而不是继承通过对耦合的分析,我们不难发现,继承就是一种耦合。如果子类A继承了父 类B,不论是直接或间接的继承,子类A都必将依赖父类B。子类A必须使用在存在父类B的环境中,父类B不存在子类A就不能使用,这样将影响子类A的可移植 性。一旦父类B发生任何变更,更改或去掉一个函数名,或者改变一个函数的参
19、数,都将导致子类A不得不变更,甚至重写。假如父类B的子类数十上百个,甚至贯 穿这个项目各个模块,这样的变更是灾难性的。这种情况最典型的例子是我们现在使用hibernate和spring设计DAO对象的方式,具体的描述参见 我写的如何在 struts + spring + hibernate的框架下构建低耦合高内聚的软件结构一文。总之,“低耦合”给软件项目带来的优点是:易于变更、易于重用。对于开发者而言,耦合原则表示程序中单个的模块应该尽可能的独立。处理一个模块时,不应该依赖另一个模块的内部工作。内聚原则是指,在一个给定的模块内部,所有的代码应该只完成一个单个的目标。IT界有一句很著名的口号:强
20、内聚、松耦合。即 使是最初级的程序员,在常常的被教导中,他也了解了这句口号的含义:我们的程序要模块化,模块要完成明确的一组关联的服务功能,要求它的各部分是相关的、 有机组合起来是完整体(外部程序来看黑盒子),模块的内部各成分之间相关联程度要尽可能高(强内聚);而模块与模块之间又要求是可分拆的、少依赖的(松耦 合)。人们易于实现强内聚的模块,例如:一个函数实现一个独立的功能,这就是强内聚。人们不易实现松耦合,因为,孤 独的模块毫无意义,只有模块间的相互协调地工作,才能实现系统的目的。而对于模块间的相互关系的设计,没有一定的经验是难以把握。耦合的强度依赖于: (1)一个模块对另一个模块的调用;(2
21、)一个模块向另一个模块传递的数据量;(3)一个模块施加到另一个模块的控制的多少;(4)模块之间接口的复杂程 度。等等。当然,“强内聚、松耦合”也是有矛盾的,如:内聚性越强,则要求的函数越多(每个函数只作一件“事”),这样,将它们组合成 “大”的功能,也就越复杂,就不可能达到松耦合。因此,应在二者之间作出平衡与折衷的选择,这也体现程序员的水平。从系统论的角度来看,系统是有层次的, 即系统可以分为子系统,模块可分为子模块,“强内聚、松耦合”的“度”的把握,应结合系统的次层性来考虑,即通常应在层次性上作出折衷,如:模块内子程序 (下一个层次上)应共享数据(有一定的耦合度),而减少全局变量能降低子程序
22、性间的耦合性。面向对象的语言进一步强化了“强内聚、松耦 合”,类的封装性既强调了相关内容(数据及其操作)的内聚,又强调了类的独立性和私密性。而类的继承性以及友元等,就是在松耦合的原则下规范了类之间的关 联关系。类与类之间通常通过接口的契约实现服务提供者/服务请求者模式,这就是典型的松耦合。“强内聚、松耦合”对于程序编写分工、程 序的可维护性以及测试都有重要的关系,如:从设计角度来看,在“强内聚、松耦合”的指导下进行的设计得到的程序模块,符合项目管理的WBS(工作分解结 构)的要求,其相对独立的模块可以分配到具体的程序员进行开发,另外,程序编码外包也必须建立在这种原则的设计之下;从程序生命期角度
23、来看,它有利于提高 程序质量,特别是方便于程序的日后维护,即程序模块的相对独立性是可维护性的保证;再从测试角度来看,符合“强内聚、松耦合”的程序,易于对局部(模块) 进行黑盒测试,也易于编写测试用的“桩”和“驱动”。“强内聚、松耦合”也是对组织结构的要求,项目组分为几个小组(正式的或非正式 的),各小组的工作应是高度相关的,各小组之间的工作应尽量是较少相关或有明确的接口,从而减少沟通成本。其实,“强内聚、松耦合”是系统中应遵守的普遍 原则,我们在许多领域都可以找到它的应用。“强内聚、松耦合”是我们不得不念的“三字经”,我们一定要念好它。高内聚和低耦合是同义词。1。高内聚,指自成一体。2。低耦合
24、,指对外部的依赖很小。只是他们侧重的角度不同,内聚侧重的是内政,而耦合侧重的是外交。 一个对象有两种外交形势,一是输出价值观,让别人调用,二是输入价值观,依赖别人。低耦合指的是输入价值观应该尽量少。如果必然要输入,那么输入的形式也有强弱之分,强耦合就是严重依赖别人。从系统角度,如果要每个对象不依赖别人,却又妄想更多的输出价值观,这是矛盾的。因此,所谓的低耦合,指的是尽量减少不必要的输入,尤其避免强耦合。从系统角度,越接近系统底层的,越具体的,耦合越强,而越高层的,越抽象的,耦合越低。上章回顾 在上篇中我们讲解了几类UML2.0语言新推出的建模图形,总体来说通过这些图形能更详细的将某类信息表达出
25、来。在这里我们简单回顾上篇讲解的内容。 上图中已经简单介绍了上章讲述的内容,具体内容请看:系统架构师-基础到企业应用架构-系统建模下篇。二、摘要 本章将主要的简单介绍在系统架构中的设计模式及相应规范准则。并结合相应的代码来说明如何遵循系统架构中的一些基本的设计规范及准则。而我们将在本文介绍几类常用的设计规范,我们先来看看结构化设计的二个基本原则: 当然既然提出了基本的准则,那么我们如何来满足准则呢,并且能更好的设计呢?我们可以通过如下手段来达到这样的要求: 当然图中演示了功能分离的策略,通过把需求按照不同的功能详细的划分开来,每个功能都是独立的,当然我们这里也可以成为是关注点。下面我们将针对这
26、些原则进行详细的讲解。三、本章内容 1、上章回顾。 2、摘要。 3、本章内容。 4、设计规范及原则。 5、如何满足设计要求。 6、本章总结。 7、系列进度。 8、下篇预告。四、设计规范及准则。 1、高内聚 首先我们来看看内聚的含义:软件含义上的内聚其实是从化学中的分子的内聚演变过来的,化学中的分子间的作用力,作用力强则表现为内聚程度高。在软件中内聚程度的高低,标识着软件设计的好坏。 我们在进行架构设计时的内聚高低是指,设计某个模块或者关注点时,模块或关注点内部的一系列相关功能的相关程度的高低。 例如:下单模块: 一般情况下,下单模块都会有如下的信息,订单的信息,产品的信息及谁下的单(买家信息)
27、。这是基本的,那么我们设计的时候就要把相关的功能内聚到一起。当然这是从大功能(下单管理)上来说,当然这些模块还可以再细化分成产品、订单、会员等子模块。 例如我们在设计数据库操作辅助类提供的方法有: 通过这样的方式,那么这个组件只负责数据库操作。这样带来的好处也是显而易见的。高内聚提供了更好的可维护性和可复用性。而低内聚的模块则表名模块直接的依赖程度高,那么一旦修改了该模块依赖的对象则无法使用该模块,必须也进行相应的修改才可以继续使用。 低内聚的模块设计的坏处有:首先模块的功能不单一,模块的职责不明确,比较松散,更有甚者是完成不相关的功能。这样的设计往往是不可取的。可以通过重构来完善。 下面我们
28、来说下高内聚的简单解释:什么样的模块算是高内聚,并且能够在系统中很好的使用。 那么我们在设计的过程中如何去完成高内聚呢? 以上基本上讲述了高内聚的好处,并且阐述了如何实现高内聚的步骤和原则。下面我们来说说可能高内聚带来的坏处。 高内聚有时候也不是说所有的情况都采用这样的原则,当然高内聚还是要适度的,下面来举例说明:例如内聚性要求强的话就像Windows32中系统提供的API,里面的函数太多了,都放在一个Dll中,那么每个函数完成一个功能。这样强大的功能,会比较复杂,所以并不是完全的高内聚越高越好,还是要看实际的需要。当然维护起来也不是特别的方便。 2、低耦合 首先我们来看看低耦合的定义:低耦合是用来度量模块与模块直接的依赖关系。耦合当然也可以这样简单的理解,我想懂电脑的应该都知道,CPU与主板之间的关系,CPU如果是特殊的CPU必须使用特殊的主板来支持,那么如果说这个CPU不唯一依赖唯一主板,那么就认为这个CPU与主板的关系是低耦合的关系。 下面我们来举例说明低耦合的设计与高耦合的设计: 这是一个简单的低耦合的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 采油工道德考核试卷含答案
- 建筑幕墙设计师安全演练强化考核试卷含答案
- 2025四川雅安雨城区定向招聘社区工作者38人备考题库附答案
- 塑料真空成型工8S考核试卷含答案
- 飞机任务系统装调工创新思维竞赛考核试卷含答案
- 电子电气产品能效检验员成果考核试卷含答案
- 电鸣乐器接装工操作技能考核试卷含答案
- 照相机及器材制造工创新意识考核试卷含答案
- 2024年湖南石油化工职业技术学院辅导员招聘考试真题汇编附答案
- 2024年滇西科技师范学院辅导员考试笔试题库附答案
- 能源行业人力资源开发新策略
- 工作照片拍摄培训课件
- 2025年海南三亚市吉阳区教育系统公开招聘编制教师122人(第1号)笔试历年典型考题(历年真题考点)解题思路附带答案详解
- 2026年孝昌县供水有限公司公开招聘正式员工备考题库参考答案详解
- 托管学校合作合同协议
- 产品销售团队外包协议书
- 2025年医保局支部书记述职报告
- 汽车充电站安全知识培训课件
- 世说新语课件
- 全体教师大会上副校长讲话:点醒了全校200多名教师!毁掉教学质量的不是学生是这7个环节
- 民航招飞pat测试题目及答案
评论
0/150
提交评论