对象和数据的主要差别就是对象有行为,行为可以看成责任职责(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. SVN的项目管理

    基于SVN的项目管理——集中与分散   我们在此处不讨论 GIT 比 SVN 好多少,也不讨论 Maven 和 Gradle 哪个好用,基于现有的开发环境,大多数公司还是采用 SVN + Maven ...

  2. 运行Dos命令并得到dos的输出文本(使用管道函数CreatePipe和PeekNamedPipe)

    function RunDOS(const CommandLine: string): string;var  HRead, HWrite: THandle;  StartInfo: TStartup ...

  3. mongodb查询分页优化

    要求不用skip 前提:1.时间倒序排列(自己现在的项目中也是按照时间倒序排列的)       2.每页显示10条数据 int limit = 10;//刚开始点击查询的时候设置十条 查询形式为 db ...

  4. Mac OS提示# 14:自己定义文件图标

    本教程的其余部分再一次错过了方法,和一些使用提示,做一些额外的,我们希望对大家有帮助.  自己定义图标      对于Mac OSX用户来说,Dashboard,Dock栏,壁纸以及各种键盘触摸板的快 ...

  5. Delphi基础Write写入结构体到文件(使用 file of myrecord就行了,真简单)

    program WriteStruct; {$APPTYPE CONSOLE} uses SysUtils; //写入结构体 type TCustomer = record ID: ]; Code: ...

  6. FreeSwitch安装和配置记录

    安装FreeSwitch 主要示例,下面的命令: git clone -b v1.2.stable git://git.freeswitch.org/freeswitch.git cd freeswi ...

  7. window.open()具体解释及浏览器兼容性问题

    一.基本的语法:window.open(pageURL,name,parameters)当中:pageURL 为子窗体路径name  为子窗体名字parameters 为窗体參数(各參数用逗号分隔) ...

  8. Dark Side of Cloud Storage —— 数据对像的分块消重

    数据对像(可以通俗地认为是文件)的分块存储具有久远的历史.长久以来,单机文件系统一直将文件切分为若干固定大小的小块.其主要目的是为了进行有效的空间管理.互联网时代,大规模数据存储逐步发展起来.出于降低 ...

  9. 标准输入的原理:cin与scanf

    1.cin 该方法 1)假设cin读取整数.会自己主动忽略换行和空格.遇到文件结束标记.cin  >> a返回的数false     int a;     while(cin >&g ...

  10. php(LAMP)开发环境配置相关问题及解决办法

    相信很多像我一样初次接触到php开发的人,在配置基本的开发环境时都是一头雾水,为此小编特写下自己在安装配置php开发环境过程中遇到的一些问题,及解决办法. 1.LAMP组合,安装centons+apa ...