DCI架构是什么?
它以字处理器中拼音检查为例,拼音检查这个行为功能放在哪里?是dictionary 还是一个全局的拼音检查器呢?无论放在哪个对象内部,都显得和这个对象内聚性不高,由此带来多个调用拼音检查行为对象之间的协作耦合,在DDD中,好像认为这种情况是使用Service服务来实现;在SOA看来,拼音检查属于一种规则,可由规则引擎实现,服务整合流程和规则。
DCI架构则不同于DDD这种有些折扣的处理方法,而是思路复位,重新考虑架构,从对象的数据object Data, 对象之间的协作the Collaborations between objects, 和表达需求用例中操作者角色之间的交互这三个出发点来考虑。个人感觉又把桥模式演习了一遍,其实Qi4j代表的Composer组合模式或Mixin不就是在运行时,把对象以前没有的行为给注射进入,达到根据运行需求搭桥组合的目的。
DCI Architecture也总结了算法和对象的关系,这点在Jdon也曾经热烈讨论过,按照OO思想,应该把算法切分塞进对象中,Eric在DDD一书中也阐述过,不要因为大量算法实现(属于“做什么”),而忽视了“是什么”,我也在函数式编程functional programming的特点
这样,DCI架构真正含义可以归结如下:
1.数据data:是领域对象中代表领域类概念的那部分。
2.场景context:根据运行时即时调用,将活的对象实例带到符合用例需求的场景中
3.交互interactions, 描述需求用户心目中角色的活动算法。
就象上图中,把场景Context看成是一张表,角色行为作为横行加入,而数据模型作为纵行加入。
具体实现,可以在运行时,通过动态反射将业务逻辑行为注射到领域模型对象中,动态语言比较方便,C++ 和 C#使用pre-load预加载,Scala使用hybrid 混合,DCI Architecture一文没有提到AOP,可以使用AOP中静态weave方式混合,现在******it等动态代理框架都支持静态weave,包括AspectJ/Spring,在编译时就将业务行为注射到模型中。
DCI Architecture一文接下来详细介绍了Scala中的traits 是如何实现这一注射的。traits 能够让方法在程序运行时注射到一个对象实例中:
trait TransferMoneySourceAccount extends SourceAccount { this: Account => // This code is reviewable and testable! def transferTo(amount: Currency) { beginTransaction() if (availableBalance < amount) { . . . . }}. . . .//通过下面特别的对象创建方式生成符合用例的源账户和目标账户val source = new SavingsAccount with TransferMoneySourceAccountval destination = new CheckingAccount with TransferMoneyDestinationAccount?
原文:http://www.jdon.com/jivejdon/thread/37976