`

使用qi4j实现DCI架构

阅读更多

我曾经DCI架构是什么? 在一文中提到Qi4j框架实现DCI 架构比较好,dzone今天就有一篇文章专门谈Implementing  DCI   in Qi4j。

DCI是一种新的构建面向对象应用的方法途径,DCI: Data数据, Context场景, Interaction交互。该文谈了如何使用DCI 构建一个REST   API。

Roles
DCI核心思想是:对象不是由单个类如POJO组成的,而是使用Roles角色来组合组装功能,再具体一点,当我们在这里说“对象Object”,是指DDD 中的实体,而不是值对象或其他。在带有保存数据的企业架构中,实体将被划分为很多Roles,每个Roles有各自的职责目标,这点可以使用Qi4j的Mixin完成(AOP),或者Scala的Traits,否则很难以实现。

Data
DCI的数据代表实体对象中的数据,数据是进行私有Mixin(Private mixin)混合的,不可以被实体对象以外对象访问,Private mixin是一个重要概念,可以在不使用private语法的情况下,让状态成为对象的私有属性。

Context
Context掌握了在一个交互场景中角色与一个特定对象实例的关系映射。COntext可以使用POJO或Qi4j的TransientComposites 实现,后者功能很强大,体现了面向组合的架构特点。

Interactions
交互是作为场景实现的方法,寻找场景中相关的角色,然后激活调用其领域方法,重要一点是,交互的方法应该对应于用户界面表现层的Action方法,也就是MVC中控制器的方法。如果你改变了你的界面,就改变相应的场景和交互。

该文结合了作者项目,演示了DCI 的使用情况,这个项目只有三个简单领域模型: Project, User, 和 Task,Task是一种可分配的角色,而Project和 User 是一种分配者的角色,User处于一种被分配的角色,这样,我们可以有一个简单场景叫InboxContext,有一个方法(或者叫交互):assign(Assignable):分配(可分配)。

Project有一个带有Task的InBox,那是我们要分配给用户的Task。但是它既可以被一个User拥有,也可以被一个特定Project拥有,这样就需要角色职责分配,更多职责发现和切分见:对象的责任与职责

切分的目标是达成这样:"assignment"不和这样场景绑定:"查询一个用户的tasks列表, 他们其中一个能够分配给这个用户",而应该是: "查询可分配者的分配Assignments列表, 选择其中一个分配给分配者"。这两者区别就是,与具体用户解耦,从对象职责行为这个新角度来考虑场景,交互和场景与具体类解耦,只和角色有关系,我们就可以在角色这个层次来思考设计。

这种方式可以让程序员侧重角色这个抽象层面来考虑,然后着重了解职责“分配”是如何工作的,而不必着眼于用户,因为用户有用户名和密码 有个人简历等等很多细节资料;如果我们以后使用Calculation替代Task,使用ClusterNode替代User,这样我们就不必修改这个系统,可以复用它了,唯一修改的就是对象和角色的映射,如果熟悉RBAC基于角色权限设计原理的话,应该对这种从角色和职责角度考虑方式的认同。

该文还使用代码表达了如何实现交互,如下代码:

InteractionContext map = new
 InteractionContext();
RootContext context = assembler.objectBuilderFactory().newObjectBuilder( RootContext.class
 ).use(stack ).newInstance();
InboxContext inboxContext = context.user( userId ).inbox();

为当前场景创造了RootContext,这是所有场景的根场景,从根场景能够创建子场景InboxContext ,其中userId用来寻找特定的User,如果使用REST 实现,这个userId就使用URL实现,比如:"/administrator/inbox" .

为了实现前面"查询可分配者的分配Assignments列表, 选择其中一个分配给分配者",代码如下:
class
 AssignmentsMixin
     implements Assignments
 {
     @This   //自动注入Data


     AssignmentsData data;

     
//选择其中一个分配给分配者


     public
 void
 assignTo( Assignable assignable, Assignee assignee )
     {
         assignable.assignTo( assignee );
         data.assignments().add( assignable );
     }

     
//查询可分配者的分配Assignments列表


     public
 Iterable<Assignable> assignments()
     {
         return
 data.assignments();
     }
 }


我们如果实现将任务Task分配给某个用户,就使用如下代码:
inboxContext.assignTo( task );


更多代码可见原文有下载。

最后,该文总结了这样做的优点:

以上代码可能多了些,但是能够完成代码的可读性, 代码的可维护性, 易于改变拓展性,如果你使用普通POJO方法,把所有职责放在一个类中,好像很简单了,一旦这个软件项目发展到一定程度,就难以拓展维护。

此外还有优点是可以重用复用,能够避免贫血模型,在目前所谓主流架构Spring或EJB 之中,你为了避免将所有行为方法放入一个大类中,将数据放在实体中,将行为分开放到服务Service中(见请问一下这样分层对不对 ),这实际破坏了封装,就是MF指责的失血模型,问题摆在那里,但是一直没有得到解决,  DCI 架构解决了这个问题。

 

和xmuzyu讨论了以Jive Jdon案例说明对象职责和SOLID原则应用 一文中的“阅读次数”到底应不应该属于帖子这个对象的属性,其实这个问题存在很多案例中,“阅读次数”可以说不是帖子的固有属性,帖子这个对象离开“阅读次数”这个属性不是不能存在,探究“阅读次数”这个属性和固有属性比如帖子的名称等是有区别的,属于一种场景属性,也就是说只有在阅读这个场景下才会发生的属性。

DCI架构本质:DCI: 对象的Data数据, 对象使用的Context场景, 对象的Interaction交互行为,我们知道,对象有数据属性和方法行为,以前我们是封装在一个对象中,为什么要封装在一个对象中?因为这个对象在某个需求用例场景中被使用时需要这些属性和方法行为,注意了,这里面有一个关键点,就是对象被使用,以前我们进行面向对象设计,是遵循一种静态原则,因为这个对象被使用需要这些属性和行为,所以,我们在编码时将这些属性和行为写在这个类中。

这个逻辑过程是不对的,那是因为过去程序语言平台落后,导致了我们这种思维逻辑,现在是的思维逻辑是:对象被使用时需要的属性和行为不必一定要在编写代码时写入,而是在运行时再注入或MiXIN混合进去。

这就是DCI 架构的本质。

我们还是以“阅读次数”这个案例分析,在以Jive Jdon案例说明对象职责和SOLID原则应用 一文我们讨论焦点集中在“阅读次数”到底应不应该属于帖子这个对象,其实这个角度有问题了,如果按照DCI 架构和对象角色职责这个架构来考虑,应该这样:

我们除去具体事物如用户和帖子,而是从角色来分析这个场景,就像上贴中存在“分配者”和“被分配者”一样,这里存在两个角色“阅读者”和“被阅读者”,而场景Context是和“阅读者”有关的一个对象,那么一个帖子被阅读的建模描述如下:
第一步:根据用户创建一个阅读场景对象:
ReadContext readcontext = RootContext.create(userId)
第二步:由阅读场景对象来执行交互行为阅读:
readcontext.view(readed);

其中readed被阅读者就是帖子。

所以,按照DCI 架构来说,阅读这个行为应该属于Context场景这个行为,只有在这个场景下才会发生阅读这个行为。

如果不按照DCI 架构来分析,我们会倾向把阅读这个行为放到“帖子”这个对象中,有人担心,以后再有“顶”这个行为,那么顶的结果数据也要放到“帖子”这个对象中,这里有一个误区,“帖子”不是一个类,不是说所有场景属性结果都放如帖子这个一个类中,帖子只是一个对象群中根实体,我们可以根据不同场景创建不同实体类或值对象,都从属于“帖子”这个根实体,组成一个边界和子领域。

当然,如果有Qi4j或AOP的Mixin来支持,我们也可以使用楼上这种DCI 架构方式。

但是个人认为,上面AssignmentsMixin类实际是和业务无关的器具技术类,如果语言本身提供AssignmentsMixin这个混合机制,就不再需要了。

另外,DCI架构中对于我们普通的POJO技术,也就是没有Mixin支持的环境中,最大的借鉴就是引入Context这个场景对象,D和I以前都有,就是对象的数据和方法,通过Context这个对象引入,使的我们的软件更加贴近需求分析中用例场景,四色原型可以说是DCI 架构的前言。

Context这个对象其实和角色动作职责有关,如果你不是管理者,你就不可能进入管理这个场景,角色是场景的前置条件,交互动作是场景的必然结果,很符合DBC设计原则。

这应该是面向对象设计领域新的革命思维。

 

DCI架构的核心是Context,场景是角色参与具体业务活动的表现,从用例图可以看出,如下图:




这张图是典型的需求用例图,这是通往软件的第一步,通常我们从用例图到软件建模,有一个转换,那是因为过去软件技术不行,只能做妥协转换,而根据DCI 架构,我们可以在软件中直接实现用例需求。

DCI架构的场景有时很象SOA中的服务,服务确实为对象被使用提供了场景,所以,很多场景是在提供服务时发生的。但是必须注意到,交互行为属于场景这个范围内,你不能忽视场景这个边界,而直接将交互行为方法写到服务中,这就造成了服务类过大,回到面向过程编程了。见这个有关Spring下的分层讨论

 

原文:http://www.jdon.com/jivejdon/thread/38266#23127442

分享到:
评论

相关推荐

    DDD领域驱动设计 DCI架构

    总的来说,DDD是一种以业务为中心的开发方法论,它强调领域建模的重要性,提倡分析设计的融合,以及通过DCI架构实现业务逻辑的清晰表达。通过DDD,开发者能够更好地应对复杂系统的挑战,构建出更符合业务需求、更...

    400G改变高带宽DCI架构

    400G技术正在深刻地改变高带宽数据中心互连(DCI)的架构,以应对不断增长的带宽需求。随着云服务提供商对全球数据中心的整合与互联,400G可插拔光模块成为了关键的技术解决方案。400G标准的出现,如400ZR、OpenZR+...

    GD32F407 DCI LWIP

    4. DCI接口编程:如何通过GD32F407的DCI接口与摄像头进行通信,实现图像数据的捕获和传输。 这样的项目可以作为学习嵌入式系统开发、实时操作系统使用、网络通信以及图像处理技术的良好实践案例。开发者需要深入...

    数据中心网络400G和DCI网络架构.pdf

    "数据中心网络400G和DCI网络架构" 以下是从文件中提取的相关知识点: 1. 数据中心网络架构的发展趋势:随着数据中心和DCI网络的发展,数据中心网络架构也在不断演进。新的技术和解决方案正在涌现,以满足日益增长...

    美团点评微服务架构实践

    在服务注册和发现的实现上,传统方式通常使用ZooKeeper进行,通过临时节点、框架直连、触发或轮询更新,但这种方式存在session timeout、ZooKeeper ACL、紧耦合、运维影响、集群不稳定、故障隔离等问题和挑战。...

    MPLS L3 VRF DCI配置.rar

    MPLS L3vrf DCI配置 https://editor.csdn.net/md/?articleId=120409937 DCI互联 Layer 3 VRF-MPLS (EVE vqfx实验)全部配置

    精读架构设计之DCI

    我们可以使用函数式Functional编程设计,可以使用面向对象OOP的设计,可以使用面向接口的思想,也可以使用AOP,可以使用注解,代理、反射,各种设计模式;在大前端辉煌发展、在数据时代的当下我们一起阅读了一篇设计...

    DM8 - DCI Program.pdf

    DM8 DCI(Data Communication Interface)是达梦数据库提供的一种编程接口,用于在应用程序和DM数据库之间建立通信,实现数据的存取和处理。DCI接口基于OCI(Oracle Call Interface),提供了与Oracle数据库兼容的...

    基于UltraScale+FPGA可编程逻辑DCI互连盒设计

    - **现场升级能力**:可编程逻辑架构的可升级性让DCI盒能够快速适应新标准和协议,而这种变更可通过软件定义网络(SDN)控制器进行编排。 - **安全性**:FPGA能够实现对进出数据中心的数据进行加密或解密的安全措施...

    rock_motive:RockMotive 为 Rails 提供 DCI 架构

    摇滚动力 RockMotive 为 Rails 提供 DCI 架构。 安装 将此行添加到您的 Gemfile 中: gem 'rock_motive' , github : 'rosylilly/rock_motive' 执照 麻省理工学院执照

    通信行业周报:中国电信采购DCI波分设备,开放光网络拉开帷幕.zip

    DCI波分复用(Wavelength Division Multiplexing, WDM)是一种光纤通信技术,通过将不同波长的光信号在同一根光纤上传输,实现了带宽资源的有效利用。这种技术允许在同一光纤上同时传输多个数据流,提高了网络容量和...

    DCI型细水口模架.zip

    4. 维护与保养:由于细小的冷却通道容易堵塞,DCI模架在使用过程中需要定期清洗和维护,以保持冷却效率,延长模具的使用寿命。 5. 设计软件应用:现代模具设计中,工程师会使用CAD/CAM/CAE软件进行模架设计,如...

    DCI format - DCI.zip

    包含DCI0-0、DCI0-1、DCI1-0、DCI1-1的解码 输入字节流,解出对应字段的内容 如0-0中。 Nrb_dl_bwp 48 payload bitstring 11010100101110101111111 频域资源分配 11 11010100101 时域资源分配" 4 1101 VRB-to-PRB...

Global site tag (gtag.js) - Google Analytics