写点什么

没有依赖注入和面向方面编程,能很好地进行领域驱动设计吗?

  • 2008-03-04
  • 本文字数:2408 字

    阅读完需:约 8 分钟

领域驱动设计(DDD)的主要思想是在设计中将业务领域中的概念与软件元素对应起来,面向对象的编程方法(OOP)是DDD 实现中的核心要素。OOP 中的对象就代表现实中某个实体。在充分利用诸如继承、封装和多态等OOP 概念的基础上, 领域对象会被设计成简单Java 类和接口。

在一个典型的业务单元中,领域对象通常需要与其他对象协同工作,无论此对象是服务(Service) 仓库(Repository) 还是工厂(Factory)。与此同时,诸如领域状态变化跟踪、审核、缓冲、事务管理(包括事务重试)之类的横切关注点也是领域对象必须密切关注的。然而,这些东西大都是可重用的并且是非领域相关的,它们往往会散布或者重复出现在包括领域层的所有代码中。这些嵌入领域代码中的非领域逻辑往往会导致领域层的繁杂与混乱。

为了很好管理代码间依赖,同时解耦领域对象与独立的横切关注点,只使用OOP 技术往往不能为领域驱动设计提供一流的设计和开发解决方案。正是由于这些原因催生了依赖注入 (DI) 和面向方面编程 (AOP) 等概念。它们作为 OOP 的补充,能很好地减少代码间紧密耦合、增加产品模块化特性和管理横切关注点。

以上就是 DomainDrivenDesign 用户组的论坛最近一个帖子讨论的主题。讨论由Ramnivas Laddad 有关DDD 的一段演讲引出,在陈述中他断言DDD 在没有AOP 和DI 辅助的情况下是无法完全实现的。Ramnivas 谈到了应用AOP 实现细粒度DI 这一概念,他认为此概念能使领域对象的行为更合理。他还提到领域对象如果想要有丰富的功能行为,就必须有权使用其他细粒度的对象,这往往是通过将服务、工厂或者仓库注入到领域对象中实现的(使用Aspects 在构造函数或者 setter 函数中进行注入 )。

管理域对象之间的依赖关系(例如实体与其仓库间依赖)是任何一个 DDD 开发者都会涉及的典型问题。通常的设计解决方法是让 Service 或者 Façade 直接调用 Repository,Repository 获得实体对象后将其返回给调用者。这种设计方式往往会导致胖服务层和贫血模型( Anemic Domain Model )的出现,结果就是 façade 类会开始堆积越来越多的业务逻辑,领域对象也逐渐变成只有一些 setter 和 getter 函数的纯粹的数据载体。

InfoQ 与 Ramnivas Laddad 和《领域驱动设计》一书的作者 Eric Evans 就 DDD 实现中 DI 和 AOP 的角色问题进行了讨论。当谈到 DDD 在没有 AOP 和 DI 辅助的情况下是无法完全实现的这一断言时,Ramnivas 认为这个结论的重要前提是领域对象如果想要表现得更灵活,与 Repositories 和 Services 这样的对象打交道是不可避免的。

问题的关键是领域对象怎样得到此类对象?DI 似乎是个正确的选择。AOP 此时也正好派上用场,它将类 Spring 的 DI(将 DI 限制在 application context 中声明的对象范围内)扩展到任意的对象,而不管它是在哪里创建的。当然,AOP 也会在任何领域层面的横切关注点上起作用(此处的基本假设是领域概念应尽可能地映射到某一软件制品上)。

Eric 在谈到 OOP、DI 和 AOP 为何非常适合实现 DDD 时说:

虽然 DDD 能用任何范式实现,只要这些范式支持抽象并且能表达领域概念就行。但在实际应用中人们的选择几乎总是 OOP。因此说 OOP 是 DDD 实践的基础。 DI 目前已经成为了一项广为人知的技术,如果应用得当,它能帮助 DDD 实践者改善设计。在我看来,最重要的还是 DI 实现了领域的隔离。

人们正逐渐认识 AOP 的潜力。这种潜力就是它可以改变领域层的杂乱状态。这对领域概念的清晰表达甚至领域隔离非常有帮助。但是,它还不是“基础”(译者注:指 OOP)的一个经受过实践检验的组成部分,在这一点上它还是跟 OOP 和 DI 有区别的。

以上这些就形成了目前支持 DDD 的最佳实践架构的基础。

他还强调说弄清设计思想(DDD)与能帮助我们实现这种思想的技术工具(OOP、DI 甚或 AOP)间的界限也是非常重要的。

近来定义和管理 Aspects 和 DI 的趋势是应用注释(Annotations)。Spring 采用 @Configurable 将 Repository 和 Services 注入到领域对象。InfoQ 就注释(Annotations)在 DDD 项目中的角色问题咨询了 Eric:

通常,任何依附于某个对象并且代表领域中某个概念的东西,包括注释(Annotation),应该在概念上与此对象有某种联系。@Configurable 属于技术范畴,并非属于领域范畴,因此我不赞成给领域对象加上这样的注释。在另一方面,对 Repository 来说,我一般会有一个接口和一个实现类。我将接口看作其中的领域部分,尽量保持其纯概念化。但是实现类往往会引用某种技术(例如 DAO 是这些技术中的典型代表)。这样在 Repository 的实现类中应用 @Configurable 注释就合情合理了。

在 @Configurable 注释之外,Spring 框架继续扩展了“领域依赖注入”的思想。Ramnivas 最近写了一篇关于 Spring2.5.2 版本( project snapshot build 379 )最新进展的博客文章。Spring2.5.2 有三个新的方面(AnnotationBeanConfigurerAspect, AbstractInterfaceDrivenDependencyInjectionAspect 和 AbstractDepndencyInjectionAspect),它们为领领域对象的依赖注入提供了简单并且灵活的选择。Ramnivas 说引入前述第二个方面(AbstractInterfaceDrivenDependencyInjectionAspect)的目的是让特定领域的注释和接口能起到应有的作用。他最后补充道 @Configurable 虽说是一个简单的选项,但它往往不是最优雅的。

目前也有了一些关于服务编排(对多步骤的业务单元来说)和业务对象生命周期的讨论。在关于 BPEL 是怎样影响领域对象生命周期和不同领域对象之间交互这一问题上,Eric 的观点是:

服务编排和对象生命周期是很微妙的一对概念。服务编排是一种将解耦的业务片段重新结合在一起同时又能描述出工作流程的重要方法。在另一方面,在领域实体有一定的生命周期并且这些周期处于建模的中心地位的情况下,让编制层来管理对象生命周期,领域对象里面就没剩多少东西了。不过此问题并没有现成的标准答案。对设计者设计好坏的评估要个别分析,不能一概而谈。

查看英文原文: Can DDD be Adequately Implemented Without DI and AOP?

2008-03-04 23:143088
用户头像

发布了 23 篇内容, 共 46514 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

讯飞推出充电宝式便携拾音器,重新定义传统拾音

Talk A.I.

区块链、AI与大数据加持,电子合同更安全、效率更高

CECBC

区块链 大数据

一期二班-吴水金-第六课作业

吴水金

架构师训练营 W06 作业

Geek_f06ede

Alibaba官方发文:阿里技术人的成长路径与方法论

Java架构师迁哥

Architecture Phase1 Week10:Summarize

phylony-lu

极客大学架构师训练营

架构师训练营 - 第五周学习总结

joshuamai

开源认证和访问控制的利器keycloak使用简介

程序那些事

开源 程序那些事 授权框架 keycloak 认证授权

Thread.start() ,它是怎么让线程启动的呢?

小傅哥

Java 线程 JVM 小傅哥 Thread

数字人民币快来了,但多数人可能会有四大误解

CECBC

数字人民币

论“万剑归宗”思想对开发设计的一点“肤浅”作用

八苦-瞿昙

随笔杂谈 设计实践

JVM-技术专题-垃圾回收策略

洛神灬殇

计算机核心课程必读书目——《高级数据结构:理论与应用》

计算机与AI

数据结构 算法

802.11抓包软件对比之Microsoft Network Monitor

IoT云工坊

wifi 嵌入式 抓包

数字经济发展势头强劲

CECBC

数字经济

mongodb 源码实现系列 - command命令处理模块源码实现一

杨亚洲(专注MongoDB及高性能中间件)

MySQL mongodb 高性能 源码剖析 分布式数据库mongodb

架构师训练营 - 第五周课后练习

joshuamai

Java踩坑记系列之BigDecimal

Java老k

BigDecimal

熬夜不睡觉整理ELK技术文档,从此摆脱靠百度的工作(附源码)

996小迁

Java 编程 架构 面试 ELK

都是“算法”惹的祸,字节三面处处坑,我的offer要凉了?

Java~~~

字节跳动 面试 编程语言 算法和数据结构

区块链医疗应用场景有哪些?区块链医疗解决方案

13530558032

智慧园区管理平台app系统开发,智慧楼宇系统搭建

13530558032

IPFS四币连发系统开发技术(四币循环模式)

薇電13242772558

区块链 数字货币

区块链防伪溯源平台搭建,助力企业品牌安全体系升级

13530558032

为什么说应用架构需要分类思维?

Java架构师迁哥

“奋斗者”号下潜10909米:我们为什么要做深海探索?

脑极体

面试者必看:Java8中的默认方法

Silently9527

java8 默认方法

家庭留白、中屏崛起与硬件棋局

脑极体

甲方日常 57

句子

工作 随笔杂谈 日常

Java踩坑记系列之Arrays.AsList

Java老k

Java

java: Compilation failed: internal java compiler error解决办法

LSJ

IDEA

没有依赖注入和面向方面编程,能很好地进行领域驱动设计吗?_架构_Srini Penchikala_InfoQ精选文章