`
jiav_net
  • 浏览: 104443 次
文章分类
社区版块
存档分类
最新评论

组件设计原则之概念篇(一)

 
阅读更多

在Robert C. Martin(Bob大叔)的《敏捷软件开发:原则、模式与实践》(Agile Software Development: Principles, Patterns, and Practices)一书中,他提出了一些用于设计组件(或包)的原则。传统的面向对象设计原则,例如SOLID、CARP、LoD等主要关注类的设计,而下面要介绍的这些原则主要用于设计组件和包的结构,一共包括六个原则:前面三个关注组件的内聚性(Cohesion),用于指导我们如何将类组包;后面三个关注组件的耦合性(Coupling),帮助我们确定组件之间的相互关系。简单来说,组件(或包)的设计也要做到“高内聚,低耦合”。Sunny认为,有些原则描述的是一种理想状况,在实际使用时更多的是尽量趋向于这些原则,通常很难做到百分之百满足这些原则,微笑

组件内聚性原则:粒度 (Principles of Component Cohesion: Granularity)

组件的内聚性原则帮助开发者决定如何将类划分到组件中。这些原则取决于这样的事实:至少已经存在一些类并且它们之间的相互关系也得以确定。因此,这些原则根据自底向上的观点对类进行划分,先分析类以及关系,再逐步对类进行组织。

重用-发布等价原则(The Reuse/Release Equivalence Principle, REP)
ŠThe granule of reuse is the granule of release.

重用的粒度就是发布的粒度。

在实际开发中,我们的重用粒度通常不是类一级的,而是组件一级的,这里所说的组件可以是Java中的jar,也可以是DLL或者共享库等。REP要求我们保持组件的重用粒度(granule of reuse)和组件的发布粒度(granule of release)一致,何谓重用、何谓发布我想大家应该都懂,吐舌头。由于重用是在组件这一级,因此可重用的组件中必须包含可重用的类,这些可重用的类以组件的方式发布给用户使用。REP要求我们从重用的角度去考虑一个组件的内容,一个组件中的类要么都可以重用,要么都不是可重用的(Either all the classes in a component are reusable, or none of them are.)。例如在一个基于Model 2的Java EE项目中,我们将所有的DAO类打包为一个jar,目的是在其他基于相同数据库的项目中能够重用所有的DAO类,在这个DAO组件中就不应该包含任何控制层(Servlet)或者表示层(JSP等)相关的类,因为这些类不能同时被重用。

此外,在实施REP时,与面向对象设计原则中的SRP(单一职责原则)类似,在一个组件中不应该包含太多不同类型的类,不要把一些完全不相干的类放在一个组件中,这样会导致组件的职责过重,增加修改和发布的频率。因此,我们应该让一个组件中的所有类对于同一类用户或者面向同一场景是可以重用的,不应该让组件中的一部分类对用户而言有用而其他类不适用。

简而言之,REP要求我们从复用的角度来设计组件,让一个组件中所有的类都能够一起被复用,不存在不能复用的类,也不存在只有在另一种场合下才能够被复用的类。复用的粒度即发布组件的粒度。

共同重用原则(The Common Reuse Principle, CRP)
ŠThe classes in a component are reused together. If you reuse one of the classes in a component, you reuse them all.

一个组件中的类需一起被重用。如果你重用了组件中的一个类,那么就要重用其中所有的类。

CRP与之前的REP通常会一起出现,同一个组件中的类作为一个整体被复用,而不是只复用其中的某一个或几个类。我个人觉得,CRP是一种理想情况,它有利于降低组件之间的耦合度,但是实现起来有一定的难度,对于一个类稍微多一点的组件,很难同时复用其中所有的类,大部分情况下都只是使用其中的部分类,微笑。我们需要做的是,尽量让这些类位于同一个组件中,减少与客户端程序交互的组件数量,降低系统耦合度。

CRP告诉我们需要将哪些类放在同一个组件中,在略为复杂一点的系统中,类很少会孤立的重用。例如,有时候需要将一个具体类和它的抽象层一起重用,需要将一个聚合类和它的迭代器一起重用,需要将工厂类和产品类一起重用,此时,最好将它们设计在同一个组件中。如果将它们分离开,放在两个不同的组件里,势必会在一些组件之间增加依赖关系,被依赖方的组件发生修改和重新发布时,依赖方的组件也需要重新验证和发布,导致维护和升级工作量增加。

此外,如果一个组件中类太多,只要该组件中一个类发生改变重新发布时,所有依赖这个组件的客户类都应该进行测试验证,看是否引入bug,即使发生修改的类与大部分客户类都没有任何关系,这样一来,导致测试工作量也会有所增加,需要进行大量不必要的重新验证和重新发行,费时费力。

CRP更多是告诉我们没有紧密联系的类不应该放在一个组件中,在一个组件中应该只包含那些需要一起被重用的类。

共同封闭原则(The Common Closure Principle, CCP)
ŠThe classes in a component should be closed together against the same kinds of changes. A change that affects a component affects all the classes in that component and no other components.

一个组件中的所有类对于同一种类型的变化应该是共同封闭的。一个变化若对一个组件产生影响,则将影响该组件中所有的类,而对其他组件不造成影响。

这个原则实际上就是组件的单一职责原则(SRP),也就是说一个组件不应该包含多个引起它发生改变的原因。在大多数应用中,可维护性比可重用性更重要。如果一个应用中的代码需要发生修改,尽量让这种修改都集中在一个组件中,而不是分散在多个组件中,例如更换数据库,只需要修改或更换与数据库操作有关的组件;更换视图层的界面,只需修改或更换新的界面组件。如果所有的更改集中在一个单一的组件中,我们只需重新发布那一个组件即可,这个组件通常也不会很巨大,易于维护和重用。如果将这些更改分散在多个组件中,将增加软件发布、验证和维护工作量。

实施CCP要求我们识别出那些关系很紧密的类,尽量将这些类封装到同一个组件中,避免后期需要修改多个组件。

CCP要求我们把对某一类型改变(例如更换数据库)敏感的类组织到同一个组件中,当需求中一个变更到来时,可以将变化限制在最少数量的组件中

总结

在考虑如何将类组织到组件中时,需要充分考虑组件的可复用性和可维护性,一起被重用的类尽量放到一个组件中,一起受影响需修改的类尽量放到一个组件中。我们还要注意,随着项目的开展,组件的组成可能会随着时间而演化,需要相应作一些调整。我们在进行初始设计时需要尽量考虑全面,降低组件的修改工作量!

【作者:刘伟 http://blog.csdn.net/lovelion

分享到:
评论

相关推荐

    网络工程师考试考点分析与真题详解.网络设计与管理篇

    14 第2章 网络系统的设计 19 2.1 技术和产品的调研和评估 19 2.1.1 网络产品 19 2.1.2 网络技术 25 2.2 网络设计的目标和原则 26 2.2.1 网络设计目标 26 2.2.2 网络设计原则 27 2.2.3 网络...

    asp.net知识库

    深入剖析ASP.NET组件设计]一书第三章关于ASP.NET运行原理讲述的补白 asp.net 运行机制初探(httpModule加载) 利用反射来查看对象中的私有变量 关于反射中创建类型实例的两种方法 ASP.Net应用程序的多进程模型 NET委托...

    网络工程师考试考点分析与真题详解.网络设计与管理篇.part4

    14 第2章 网络系统的设计 19 2.1 技术和产品的调研和评估 19 2.1.1 网络产品 19 2.1.2 网络技术 25 2.2 网络设计的目标和原则 26 2.2.1 网络设计目标 26 2.2.2 网络设计原则 27 2.2.3 网络...

    MFC Windows程序设计(第2版修订版)--源代码

    本书的作者,jeff prosise,用其无与伦比的技巧向读者讲述了mfc程序设计中的基本概念和主要技术——再次阐释了在32位windows平台上进行了快速的面向对象开发的完美方法。  本书涵盖了以下专题:  事件驱动程序设计...

    网络工程师考试考点分析与真题详解.网络设计与管理篇.part5

    14 第2章 网络系统的设计 19 2.1 技术和产品的调研和评估 19 2.1.1 网络产品 19 2.1.2 网络技术 25 2.2 网络设计的目标和原则 26 2.2.1 网络设计目标 26 2.2.2 网络设计原则 27 2.2.3 网络...

    网络工程师考试考点分析与真题详解.网络设计与管理篇.part2

    14 第2章 网络系统的设计 19 2.1 技术和产品的调研和评估 19 2.1.1 网络产品 19 2.1.2 网络技术 25 2.2 网络设计的目标和原则 26 2.2.1 网络设计目标 26 2.2.2 网络设计原则 27 2.2.3 网络...

    网络工程师考试考点分析与真题详解.网络设计与管理篇.part3

    14 第2章 网络系统的设计 19 2.1 技术和产品的调研和评估 19 2.1.1 网络产品 19 2.1.2 网络技术 25 2.2 网络设计的目标和原则 26 2.2.1 网络设计目标 26 2.2.2 网络设计原则 27 2.2.3 网络...

    网络工程师考试考点分析与真题详解.网络设计与管理篇.part6

    14 第2章 网络系统的设计 19 2.1 技术和产品的调研和评估 19 2.1.1 网络产品 19 2.1.2 网络技术 25 2.2 网络设计的目标和原则 26 2.2.1 网络设计目标 26 2.2.2 网络设计原则 27 2.2.3 网络...

    网络工程师考试考点分析与真题详解.网络设计与管理篇.part7

    14 第2章 网络系统的设计 19 2.1 技术和产品的调研和评估 19 2.1.1 网络产品 19 2.1.2 网络技术 25 2.2 网络设计的目标和原则 26 2.2.1 网络设计目标 26 2.2.2 网络设计原则 27 2.2.3 网络...

    MFC Windows程序设计(第2版修订版)--详细书签版1卷

    本书的作者,jeff prosise,用其无与伦比的技巧向读者讲述了mfc程序设计中的基本概念和主要技术——再次阐释了在32位windows平台上进行了快速的面向对象开发的完美方法。  本书涵盖了以下专题:  事件驱动程序设计...

    MFC Windows程序设计(第2版修订版)--详细书签版2卷

    本书的作者,jeff prosise,用其无与伦比的技巧向读者讲述了mfc程序设计中的基本概念和主要技术——再次阐释了在32位windows平台上进行了快速的面向对象开发的完美方法。  本书涵盖了以下专题:  事件驱动程序设计...

    软件工程完整ppt

     42软件设计的概念和原理  421模块和模块化  422抽象  423信息隐蔽和局部化  424模块独立性及其度量  43软件结构设计准则  44软件结构设计的图形工具  441软件结构图  442层次图  443HIPO图  45结构化...

    VB2008应用程序开发实例精讲(光盘文件)

     《VisualBasic2008应用程序开发实例精讲》语言简洁,内容丰富,结构合理,突出了应用性、实用性两个基本原则。不但详细介绍了VB 2008各种领域的应用开发技术,而且提供了相关理论知识、设计思路与实现方案,侧重于...

    ASP.NET3.5从入门到精通

    3.1.3 面向组件的概念 3.2 面向对象的C#实现 3.2.1 定义 3.2.2 创建一个类和其方法 3.2.3 类成员 3.2.4 构造函数和析构函数 3.3 对象的生命周期 3.3.1 类成员的访问 3.3.2 类的类型 3.3.3 .NET 的垃圾回收机制 3.4 ...

    ASPNET35开发大全第一章

    3.1.3 面向组件的概念 3.2 面向对象的C#实现 3.2.1 定义 3.2.2 创建一个类和其方法 3.2.3 类成员 3.2.4 构造函数和析构函数 3.3 对象的生命周期 3.3.1 类成员的访问 3.3.2 类的类型 3.3.3 .NET的垃圾回收机制 3.4 ...

    java版飞机大战源码-shared-code-in-microservices:关于微服务中的共享代码的博客文章

    java版兵器大战 微服务中的共享代码? 领域驱动设计的救命稻草 微服务已经存在了一段时间,因此它们是最先进的,而不仅仅是炒作。...引入微服务的核心目标之一是解耦在技术自主下设计和实现的组件,

    亮剑.NET深入体验与实战精要2

    13.6 面向对象设计的原则 478 13.6.1 优先使用(对象)组合,而非(类)继承 478 13.6.2 针对接口编程,而非(接口的)实现 481 13.6.3 开放-封闭法则(OCP) 482 13.6.4 Liskov替换法则(LSP) 485 13.6.5 单一...

    亮剑.NET深入体验与实战精要3

    13.6 面向对象设计的原则 478 13.6.1 优先使用(对象)组合,而非(类)继承 478 13.6.2 针对接口编程,而非(接口的)实现 481 13.6.3 开放-封闭法则(OCP) 482 13.6.4 Liskov替换法则(LSP) 485 13.6.5 单一...

Global site tag (gtag.js) - Google Analytics