对象和数据的主要差别就是对象有行为,行为可以看成责任职责(responsibilities以下简称职责)的一种,理解职责是实现好的OO设计的关键。“Understanding responsibilities is key to good object-oriented design”—Martin Fowler 。

  《对象设计:角色、责任和协作"(Object Design: Roles, Responsibilities, and Collaborations)》一书对对象的职责进行了完整阐述。

  对象过去一直被看成是被操作的数据,这也是失血贫血模式的来由,这还是一种将对象看成数据结构或集合的另外一种表现,对象是有自主行为的,对象是一种类似机器人的概念。

  职责的革命影响力

  在DDD领域驱动设计中,通常很多人会误将现实中实体完全映射到软件中领域实体,这是一种谬误,现实中实体不是一对一反映到软件中,这其中包括一个抽象过程。我们必须明白:软件领域中一个实体对象通常能够扮演多个现实中的实体角色。

  由于软件领域中对象根据不同场景可以扮演不同角色,对象的方法可以看成这些角色不同职责的表现,打个比喻:你在家是一个父亲,在单位是一个领导,如果我们建立两个实体父亲和领导就不合适了,没有经过抽象分析,其实只有一个领域模型实体,就是“你”,只不过在不同场景,你扮演不同角色,角色不同反映在角色的权利或职责行为不同,父亲的职责责任与领导的职责责任是不一样的。

  同一个领域对象通过不同方法扮演不同角色就带来实现上的一个问题,这就衍生出一种DCI架构。我们建模时,不可能将其扮演的所有角色行为都塞入实体对象中,而是应该根据不同运行场景来动态分配职责。所以,传统OO语言如Java, C#等有些难点,当然可以通过AOP的MIXIN方式变相达到,但是不是很优雅。Qi4J所谓面向组合概念实际就是这样,而Jdonframework则从EDA事件驱动方面婉转来通过事件消息来驱动不同职责响应,最新面向函数式语言如Scala这方面就优雅直接了。

  职责概念给OO世界带来巨大革命性变化,使得我们分析需求必须从职责驱动重新看待需求了。DDD一书中分析货运这个案例时,也未能从职责来审视。比如它为运输历史专门建立一个记录对象,如果从职责概念看,运输对象应该知道它自己过去的历史,这是它的职责。所以,运输历史获得应该是运输实体对象的一个方法,而不应该为其单独建立对象。

  DDD一书很多方面还是存在数据提取的影子,这是它的历史局限造成的,为了摆脱失血模式纯粹数据对象的影子,对象的职责上升到前所未有的高度。

  如何发现职责

  如果改变传统将对象看成是静止的实体概念,将实体对象看成是活的,你就很容易发现其行为职责,现实世界的对象可能是做事情或代表一些信息或东西,但是现实对象不做决定。软件中对象是活的,根据分配给他们的职责能做决定,类似智能机器人。

  职责来自于你的软件是如何工作,来自于软件的HOW。寻找和分配职责需要灵感,是一个创造性活动,是一个充满探索冒险发现新奇的乐趣活动,从下面几个方面寻找需求中职责:

  1. 来自用例分析中序列图消息发送。

  2. 构造invention、 约束表达、策略、算法、规格Specification和描述Description都可以成为职责。

  3. 系统要做的事情或要管理的信息

  4. 将实体对象看成一个演员(拟人化),扮演一个角色应该知道哪些事情knows something、会做那些事情do sth.,能够控制或决定什么事情。

  简明扼要,判断职责的主要就是:它是否知道know这些东西,它是否会做这些东西,或做一些判断决定等。

  职责分配

  将职责分配给对象,使得对象有形有态。

  按照高内聚原则分配。

  使用“如果没有这个职责,会怎样”。

  如果发现职责太广泛,不能分配到单个对象中,那么就切分职责,由这些小职责组合成更大职责。

  所谓高内聚原则:和DDD中的高聚合概念比较类似,关注类内部;一个类是否充分实现其职责目标?类中方法是否都是为实现这个职责服务的?高聚合代表系统的健壮性、重用性和可理解性。

  总结

  一旦领域对象具有丰富的行为,变成富模型,或充血模型,它实际上就是一个Actor,Actor之间可以通过协作消息进行联系,而Scala的不同于多线程机制的Actor模型底层实现又更好地支撑了这样的富模型,这也是为什么Scala开始非常流行的原因之一。

  使用职责来分析需求,建立丰富对象,类似文学中的拟人化手法,将设计想象要赋予现实中静止不会说话的客观事物。当然,不能过,合适即可,目前最大问题是不够。

http://kb.cnblogs.com/page/142268/

Understanding responsibilities is key to good object-oriented design(转)的更多相关文章

  1. What is Object Oriented Design? (OOD)

    Object Oriented Design is the concept that forces programmers to plan out their code in order to hav ...

  2. 面向对象设计Object Oriented Design

    http://www.codeproject.com/Articles/93369/How-I-explained-OOD-to-my-wife http://www.cnblogs.com/niyw ...

  3. CSharpGL - Object Oriented OpenGL in C#

    Object Oriented OpenGL in C#

  4. Object Oriented Programming python

    Object Oriented Programming python new concepts of the object oriented programming : class encapsula ...

  5. Java - 面向对象(object oriented)计划 详细解释

    面向对象(object oriented)计划 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24058107 程序包括 ...

  6. OO开发思想:面向对象的开发方法(Object oriented,OO)

    面向对象的开发方法(Object oriented,OO)认为是好文章吧,拿来分享一下(转载) 面向对象的开发方法(Object oriented,OO) 从事软件开发的工程 师们常常有这样 的体会: ...

  7. JavaScript: Constructor and Object Oriented Programming

    Constructor :  Grammar: object.constructor Example: Javascript code: 1 function obj1() { this.number ...

  8. 面对对象编程(OOP, Object Oriented Programming)及其三个基本特性

    一千个读者,一千个哈姆雷特.对于面对对象编程,书上都会告诉我们它有三个基本特性,封装,继承,多态,但谈起对这三点的见解,又是仁者见仁智者见智,感觉还是得多去编程中体验把 . 面向对象编程(OOP, O ...

  9. Python学习札记(三十) 面向对象编程 Object Oriented Program 1

    参考:OOP NOTE 1.面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. ...

随机推荐

  1. .NET Page页面事件执行顺序,以及其作用(OnPreInit()、OnInit()等)

    以按钮事件为测试标准 1. OnPreInit //检查 IsPostBack 属性来确定是不是第一次处理该页. //创建或重新创建动态控件. //动态设置主控页. //动态设置 Theme 属性. ...

  2. Hibernate获取Connection

    package com.trendcom.base.util; import java.sql.Connection; import java.sql.SQLException; import jav ...

  3. 网络编程API-上 (基本API)

    htons.ntohs.htonl和ntohl函数 Linux提供了4个函数来完毕主机字节序和网络字节序之间的转换 #include <netinet/in.h> uint16_t hto ...

  4. 枚举类型互相转换(使用GetEnumName和TypeInfo两个函数)

    usesClasses,TypInfo ; typeTCommandType = (ctEmptyCommand,ctAdd,ctModify); TCommandTypeConvert=classp ...

  5. niu人

    金步国简历 金步国简历 基本资料 姓名 金步国 性别 男 年龄 30 籍贯 江苏 淮安 院校 同济大学 专业 土木工程 学历 本科肄业 工作经验 5年 期望地点 长江以南 期望薪水 18000/月 个 ...

  6. poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)

    转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...

  7. CSS 文本框里添加按钮的实现

    有很多人做界面会经常发现设计师设计出这样的界面: 咋一看是一个文本框里加了一个按钮,经过谷歌之后,未发现在文本框里可以添加按钮. 但可以通过div来实现它. 我的做法是先做一个大小的div,然后用带里 ...

  8. [C++]指针浅析

    Date: 2014-1-4 summary: 指针的简单理解,概念性的东西会比较多(100个人有100种理解,此处只代表我个人看法) Contents: 1.什么是指针 c++ primer plu ...

  9. Jar包转成Dll的方式(带嵌套的jar也能做)

    研究很好几天,终于成功了.因为写了一个Java的项目,现在要求要改写成C#版本的.但是其中用到了svnkit,svnkit是java平台的.改写成C#的话,要使用SharpSVN,但是SharpSVN ...

  10. Python heapq 模块的实现 - A Geek's Page

    Python heapq 模块的实现 - A Geek's Page Python heapq 模块的实现