`
pitt_xu
  • 浏览: 6328 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

贫血/充血模型转贴+自己的想法

    博客分类:
  • java
阅读更多

   Martin Fowler很早以前就写过一篇文章,题目叫"贫血模型"。文章里面批判贫血的领域模型是不够优雅、不够OO的,提倡使用充血的领域模型。在Java世界里这是一直争论的话题。到底什么是贫血什么是充血呢?

  贫血模型:是指领域对象里只有get和set方法,或者包含少量的CRUD方法,所有的业务逻辑都不包含在内而是放在Business Logic层。

      优点是系统的层次结构清楚,各层之间单向依赖,Client->(Business Facade)->Business Logic->Data Access(ADO.NET)。当然Business Logic是依赖Domain Object的。似乎现在流行的架构就是这样,当然层次还可以细分。

      该模型的缺点是不够面向对象,领域对象只是作为保存状态或者传递状态使用,所以就说只有数据没有行为的对象不是真正的对象。在Business Logic里面处理所有的业务逻辑,在POEAA(企业应用架构模式)一书中被称为Transaction Script模式。

  充血模型:层次结构和上面的差不多,不过大多业务逻辑和持久化放在Domain Object里面,Business Logic只是简单封装部分业务逻辑以及控制事务、权限等,这样层次结构就变成Client->(Business Facade)->Business Logic->Domain Object->Data Access。

       它的优点是面向对象,Business Logic符合单一职责,不像在贫血模型里面那样包含所有的业务逻辑太过沉重。

       缺点是如何划分业务逻辑,什么样的逻辑应该放在Domain Object中,什么样的业务逻辑应该放在Business Logic中,这是很含糊的。即使划分好了业务逻辑,由于分散在Business Logic和Domain Object层中,不能更好的分模块开发。熟悉业务逻辑的开发人员需要渗透到Domain Logic中去,而在Domian Logic又包含了持久化,对于开发者来说这十分混乱。  其次,因为Business Logic要控制事务并且为上层提供一个统一的服务调用入口点,它就必须把在Domain Logic里实现的业务逻辑全部重新包装一遍,完全属于重复劳动。

   如果技术能够支持充血模型,那当然是最完美的解决方案。不过现在的.NET框架并没有ORM工具(不算上开源的NHibernate,Castle之类),没有ORM就没有透明的持久化支持,在Domain Object层会对Data Access层构成依赖,如果脱离了Data Access层,Domain Object的业务逻辑就无法进行单元测试,这也是很致命的。如果有像Spring的动态注入和Hibernate的透明持久化支持,那么充血模型还是能够实现的。

个人看了这篇文章以后感觉还是有种对充血模型的向往 因为一直以来也不知道是自己钻牛角尖还是什么的 对于业务层混乱复杂的业务方法 还是希望能让领域模型自己去处理这些问题 但是对于业务层的重复定义方法也是不可避免的 长远考虑领域模型重用的话还是有好处的(虽然不一定会再用到) 最终通过orm工具对领域模型的持久化感觉这种方式还是挺不错的

分享到:
评论
8 楼 eivenchan 2007-12-24  
但是在充血模型中,有些finder方法是不是应该定义成static的?
因为这些方法不是跟特定的Domain Object有关的,而是所有Domain Object有关。
这样的话,模型中将会充斥大量static的方法。
给Mock Object模式的应用带来了一定的难度。
7 楼 pitt_xu 2007-12-24  
的确是这样的 CRUD为主的项目还是简单处理比较好
6 楼 fhjxp 2007-12-24  
<p>
pitt_xu 写道
ecsun 写道
采用贫血模型,还是充血模型,要根据项目团队的整体技术情况而定,如果一个项目团队里,大多是新手,那么使用充血模型,肯定会有一定的阻力,相反,如果团队成员大多是老鸟,那就很方便了
能有一个这样的团队,写代码一定会挺愉快的 至少设计一个合理的模型是一件很有成就感的事毕竟的定义值对象挺乏味的 而在业务逻辑层看复杂的业务逻辑代码也挺头大
</p>
<p>跟项目的复杂度关系更大些吧!自己感觉(没有任何数据支持)绝大多数项目90%用户请求都是挺简单的业务操作。就我接触到的Web系统,至少都分为Action-Sevice-Dao这样三层,很多方法已经是简单的代理而已,根本就不存在业务层很重的说法。充血模型在这样的系统中只会认为增加复杂度</p>
5 楼 pitt_xu 2007-12-24  
zengcuoan 写道
假设我的业务就是加进来之后, 结合user 和 role的信息校验呢?


pitt_xu 写道
zengcuoan 写道
可是 领域模型 里的持久化都是自动的,我觉得这很危险

比如
  执行了一句: user.addRole(role)

我的原意是先加一个role到内存中,然后再在内存中做校验
但是 按领域模型 的常见模式,这个role会被自动放到数据库中,这并不是我想要的。


我想是否可以在addRole当中实现校验逻辑
一般的话userDao.store(user) 这样操作将user持久到数据库吧
自动的话应该也会在方法中做合法性校验的


其实对于充血和贫血毕竟没必要太强求什么
对于实际应用来讲 我觉得领域模型对业务逻辑的封装 并不是能满足所有问题的 也可以在业务层做更多操作的 有很多好的经验可以借鉴的
4 楼 zengcuoan 2007-12-24  
假设我的业务就是加进来之后, 结合user 和 role的信息校验呢?


pitt_xu 写道
zengcuoan 写道
可是 领域模型 里的持久化都是自动的,我觉得这很危险

比如
  执行了一句: user.addRole(role)

我的原意是先加一个role到内存中,然后再在内存中做校验
但是 按领域模型 的常见模式,这个role会被自动放到数据库中,这并不是我想要的。


我想是否可以在addRole当中实现校验逻辑
一般的话userDao.store(user) 这样操作将user持久到数据库吧
自动的话应该也会在方法中做合法性校验的
3 楼 pitt_xu 2007-12-24  
ecsun 写道
采用贫血模型,还是充血模型,要根据项目团队的整体技术情况而定,如果一个项目团队里,大多是新手,那么使用充血模型,肯定会有一定的阻力,相反,如果团队成员大多是老鸟,那就很方便了

能有一个这样的团队,写代码一定会挺愉快的
至少设计一个合理的模型是一件很有成就感的事
毕竟的定义值对象挺乏味的 而在业务逻辑层看复杂的业务逻辑代码也挺头大
2 楼 pitt_xu 2007-12-24  
zengcuoan 写道
可是 领域模型 里的持久化都是自动的,我觉得这很危险

比如
  执行了一句: user.addRole(role)

我的原意是先加一个role到内存中,然后再在内存中做校验
但是 按领域模型 的常见模式,这个role会被自动放到数据库中,这并不是我想要的。


我想是否可以在addRole当中实现校验逻辑
一般的话userDao.store(user) 这样操作将user持久到数据库吧
自动的话应该也会在方法中做合法性校验的
1 楼 zengcuoan 2007-12-24  
可是 领域模型 里的持久化都是自动的,我觉得这很危险

比如
  执行了一句: user.addRole(role)

我的原意是先加一个role到内存中,然后再在内存中做校验
但是 按领域模型 的常见模式,这个role会被自动放到数据库中,这并不是我想要的。

相关推荐

    对贫血和充血模型的理解

    贫血模型和充血模型是两种在软件开发,尤其是面向对象编程中常见的设计策略,主要应用于领域驱动设计(Domain-Driven Design, DDD)中。这两种模型主要关注于业务逻辑和数据之间的关系,以及如何在软件架构中有效地...

    失血贫血充血胀血模型.docx

    贫血模型可以看作是失血模型的一种变体,也是将数据模型和业务逻辑分离,但领域对象可能会包含一些基本的数据验证逻辑。与失血模型相比,贫血模型的领域对象稍有"血色",但仍然缺乏复杂的行为。 优点: 1. 简单明了...

    充血模型设想实现(2010/07/30更新)

    充血模型强调对象应该拥有自己的行为和状态,而不是简单地作为数据容器。这个模型与贫血模型相对,后者通常由无行为的POJO(Plain Old Java Object)或DTO(Data Transfer Object)组成,业务逻辑被分离到服务层。 ...

    贫血模型or领域模型

    贫血模型or领域模型的举例对比,让你初步了解贫血模型与领域模型的区别和概念

    浅谈Asp.net中使用“充血模型”1

    在Asp.net开发中,"充血模型"是一种提倡领域对象拥有丰富行为和业务逻辑的设计模式,相对应于传统的"贫血模型"。"贫血模型"通常将数据模型、业务逻辑和数据访问分离,使得领域对象仅包含属性,而业务逻辑和数据操作...

    11丨实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?1

    总的来说,选择贫血模型还是充血模型,取决于项目的需求、团队的技术水平以及对代码质量的要求。在实践中,理解这两种模型的优缺点,并根据具体场景灵活选择,是提升软件开发效率和质量的关键。

    C/C+HA骨植入材料对杂交波尔山羊生理生化机能的影响 (2008年)

    采用杂交波尔山羊作为动物实验模型,开展了C/C + HA复合材料骨内植入实验,并从呼吸、心跳、消化、血液和免疫等方面考察了该植入材料对实验动物生理、生化指标的影响,进而探讨了该材料的生物安全性。结果表明:在植入...

    地中海贫血与产前诊断.pptx

    β-地贫则是另一种常见的地中海贫血类型,其基因型包括正常(β/β)、杂合子(轻型,如βO/β、β+/β)以及重型(如βO/β+、βO/βO、β+/β+)。β地贫的临床特征从轻度无症状到重度贫血,需要依赖输血维持生命...

    基于GO的六边形架构框架,可支撑充血的领域模型范式代码实现.rar

    在传统的贫血模型中,领域对象通常只包含数据,而业务逻辑则分散在服务层或其他地方。然而,在充血模型中,领域对象不仅包含了数据,还封装了大量的业务逻辑。这种方法使得领域模型更加生动且有力量,因为它们可以...

    领域模型说明及范例代码.zip

    领域模型(Domain Model)和贫血模型(Anemic Domain Model)是两种常见的模型设计模式,它们各有特点,适用于不同的场景。本资料包旨在通过实例对比,帮助初学者理解这两种模型的区别和概念,并提供实际的Java代码...

    领域模型驱动设计1553265830.pdf

    - 领域模型设计:采用充血模型而非贫血模型,并且在设计中融合设计模式、流程编排、事件驱动等元素。 - 强化单测:确保代码的质量,通过单元测试来保证各个领域模型的正确性和稳定性。 - 持续重构:在业务生命周期内...

    重型再生障碍性贫血患者CD8+HLA-DR+ T淋巴细胞效应因子表达水平的变化

    重型再生障碍性贫血患者CD8+HLA-DR+ T淋巴细胞效应因子表达水平的变化,刘春燕,付蓉,目的 检测重型再生障碍性贫血(SAA)患者外周血CD8+HLA-DR+ T淋巴细胞效应因子水平,探讨SAA患者CD8+HLA-DR+ 效应T细胞损伤骨髓...

    重型再生障碍性贫血患者CD8+效应T细胞损伤骨髓造血途径的研究

    重型再生障碍性贫血患者CD8+效应T细胞损伤骨髓造血途径的研究,冯乐,付蓉,目的 研究重型再生障碍性贫血(SAA)患者外周血CD8+CD25+和CD8+HLA-DR+ T数量及其杀伤靶细胞的途径,探讨SAA的免疫发病机制。 方法 应用流...

    领域驱动设计案例-盒马实践

    领域模型可以分为失血模型、贫血模型和充血模型三种类型。 失血模型 失血模型是基于数据库的领域设计方式,它指的是使用 POJO 数据对象来存储业务数据。在失血模型中,业务逻辑是分散的,分布在多个地方。 贫血...

    行业分类-设备装置-一种建立小鼠重型再生障碍性贫血模型的方法.zip

    标题中的“行业分类-设备装置-一种建立小鼠重型再生障碍性贫血模型的方法”表明了这个文件内容涉及医学研究领域,特别是动物模型的构建,具体是关于小鼠的重型再生障碍性贫血(Severe Aplastic Anemia, SAA)模型。...

    刚果民主共和国人类免疫缺陷镰状细胞性贫血Duffy-46C / C中的血清阳性病毒—以金沙萨和卢本巴希市为例

    纯合镰刀状细胞病由于其病情伴有慢性溶血性贫血,因此在其一生中经历了多次输血,感染的风险最具说服力,例如,相对于某些病毒(如HIV),即肝炎病毒。 这项研究旨在确定镰状细胞性贫血Duffy-46C / C中的HIV血清阳性...

    肉苁蓉多糖对骨髓抑制性贫血小鼠造血调控的实验研究

    3. 实验方法:研究者采用了CO60放射源进行照射,并结合环磷酰胺(CTX)注射制备骨髓抑制性贫血模型,这是模拟放化疗导致骨髓损伤的常用方法。通过这种模型能够观察到小鼠造血功能受到抑制后,肉苁蓉多糖的干预作用。...

    主治医师 (临床医学检验学)-贫血概述(A1-A2型题).doc

    根据这些特征,可能的贫血类型包括珠蛋白生成障碍性贫血、缺铁性贫血、巨幼细胞贫血、铁粒幼细胞贫血以及慢性感染或慢性炎症性贫血。 2. 案例2中的44岁女性患者,血红蛋白55g/L,红细胞2.10×10^12/L,根据世界卫生...

Global site tag (gtag.js) - Google Analytics