网易首页 > 网易号 > 正文 申请入驻

听说过「DCI」吗?

0
分享至

这里是Z哥的个人公众号

每周五11:45 按时送达

当然了,也会时不时加个餐~

我的第「229」篇原创敬上

大家好呀,好久不见,我是Z哥。

在我最近消失的这段时间里,有些小伙伴微信问我去哪了,老读者应该知道哈,Z哥自从换了工作后的确太忙,打理公众号的时间都用来加班了。一晃眼,不知不觉都过去4个月了,太惭愧了。

不过最近收获还挺多的,我接下来慢慢花时间整理出来分享给大家。

前几周和团队里的「DDD」爱好者交流的时候,有人提到了一个概念叫「DCI」。我当时就想我只知道「DI」和「CI」,「DCI」又是什么鬼。

后来在网上搜了一下才发现在 2009 年这个概念就被提出来了,当时的文章是《The DCI Architecture: A New Vision of Object-Oriented Programming》。

DCI 中的 3 个字母分别代表:Data,Context,Interactive。在我看来,这 3 个概念共同配合表达出了某个“角色”做的事情:

「谁/什么东西(Data)」-「在什么场景下(Context)」-「做什么事(Interactive)」

比如,当你在家里打扫卫生的时候,你的角色其实是“清洁工”;当你在家里烧饭的时候,你的角色是“厨师”;当你在家里运动的时候,你的角色是“运动者”。你看,同样的一个人在不同场景下所产生的行为都与当时所处的角色有关。

DCI 的核心就是那个 Interactive,也是“角色”这个概念存在的地方。

我们来举个例子看看它的作用。

就拿前面提到的例子来看,如果我们只是识别出其中的实体是 Person,那么自然打扫卫生的方法 Clean(),以及烧饭的方法 Cook(),和运动的方法 Exercise()自然而然就落到了 Person 这个实体上。那么问题就来了,一个人在社会生活中需要做的事情有很多,如果按照这个思路,Person 这个实体将成为一个上帝类。


func (p Person) Clean() {fmt.Println("Clean")
func (p Person) CookFood() {fmt.Println("CookFood")
func (p Person) Sport() {fmt.Println("Sport")
type Person struct {Name stringAge int

同时,如果有某个领域服务或者实体上的方法以 Person 作为参数,那么其内部将可以任意调用 Clean()、Cook() 或者 Exercise()。


func MethodA(p Person){p.Clean()p.CookFood()p.Sport()

这很明显与 OO 思想中的核心概念「高内聚低耦合」背道而驰,违反了「迪米特法则」。

而函数式编程的三层架构之所以流行了很多年,就是因为它的世界里主要关注的是颗粒度最小的「方法」应该放到三层中的哪一层,而对「方法」在某一层内放到哪个对象之中是没有明确规定的。 因此在上面的例子中,如果我们将Clean()、Cook() 和 Exercise() 分别写在不同的 XXXService 中,并同时接收 Person 作为入参,那么可以轻松地消除“上帝类”,但与此同时 Person 也成为了一个只有属性的「贫血模型」。

因此 DCI 的提出就是通过一个新的视角来定义对象,它通过增加一层概念——「角色」,将传统 DDD 中对象上的非通用方法转移到了不同的角色对象中,避免了需要在一个对象上同时表达“是什么”和“能做什么”而可能出现的「上帝类」问题。 同时,通过由多个角色组成的对象也避免了「贫血模型」的发生。

接下来看看如何使用 DCI 来重新设计上面的代码。

其实很简单,将 Person 设计成由 3 个角色 Cleaner、Cook、Sporter 组成,在每个角色中分别定义 Clean()、Cook() 和 Exercise()方法。


type Cleaner interface {Clean()
type Cook interface {CookFood()
type Sporter interface {Sport()
type Person struct {Name stringAge int
func (p Person) Clean() {fmt.Println("Clean")
func (p Person) CookFood() {fmt.Println("CookFood")
func (p Person) Sport() {fmt.Println("Sport")
func DoSomeThing(cook Cook) {fmt.Println("DoSomeThing")cook.CookFood()
func main() {var p Personp.Clean()p.CookFood()p.Sport()DoSomeThing(p)

如此一来,我们可以将一些使用 Person 作为入参的方法调整成相应的角色,以达到「迪米特法则」所提倡的效果。

我们再想深入一步,Cook() 和 Clean() 的实现中都需要“拿起东西”,这是一个和角色无关的行为,那么可以将它直接定义在Person中。


func (p Person) TakeUp(thing string) {fmt.Println(fmt.Sprintf("%s TakeUp a %s", p.Name, thing))
func (p Person) Clean() {p.TakeUp("扫帚")fmt.Println("Clean")
func (p Person) CookFood() {p.TakeUp("锅子")fmt.Println("CookFood")

在 DCI 中,将角色上定义的方法称作「Role Method」,将对象(Data)上定义的方法称作「Local Method」。 前者是填充业务逻辑的地方,而后者更像是对象(Data)自身天然具有的能力,与业务逻辑无关。

上面的这整套实现逻辑在 DCI 中被称作 Methodless Role,与之对应的还有 Methodful Role 的实现逻辑,在这里就不展开了。顾名思义就是在角色的定义上更丰富,将「Local Method」也定义出来。

另外,增加一层「角色」的概念后,我们可以发现,任何具有相同行为的对象都可以给他设置同一个角色。比如,机器人也可以打扫,那么这个 Cleaner 的角色也可以定义到 Robot 对象中,而不仅仅是 Person 对象。只不过,Robot.Clean() 的实现不是“拿起扫帚”,而是“制定一个行走路线”,然后它自己会把垃圾吸到自己身体里。

可能你会问,Context 呢?好像一直没提到它该怎么实现?以 Z 哥目前的理解来看,Context 所做的事情其实和传统 DDD 中的 Applicaion 层做的事情是重合的,只是代码结构的不同。因此,我认为这部分倒不是重点,你可以按照原先的 Application 层代码来写,相当于每一个 Application 层中的方法就是一个 Context。

本质上说,DCI 是一种 “角色接口” 设计思想,如果习惯 OO 编程的小伙伴应该是很熟悉这种写法的。

好了,我们总结一下。

这篇呢,Z哥和你分享了我对 DCI 的了解。

它通过引入「角色」的概念,将传统 DDD 建模时赋予「对象」的两个职责“是什么”和“能做什么”中的后者拆分到「角色」中去定义,避免上帝类问题。 同时,因为角色最终还是会作用到「对象」上,所以也不会出现函数式编程中的贫血模型问题。

DCI 中,对定义在「角色」上的方法称为 Role Method,而直接定义在「对象」上的方法称作 Local Method。

对于「角色」在编码的实现,一般建议使用 interface 的方式来体现,因为“角色只定义行为”,具体行为要怎么做,由所在的对象来实现。如此符合「依赖倒置原则」的场景自然适合用 interface 来实现。

最后,Z 哥再分享一个实践 DCI 的思路给你。

首先是什么时候需要用 DCI?当你在实践 DDD 的过程中,觉得某个对象过大了,有点上帝类的味道,这时候就可以想一下是否可以通过 DCI 来重新设计一下。

如何落地DCI?分为以下四步:

  1. 识别领域场景

  2. 罗列其中的业务行为

  3. 分析这些定位属于什么角色,定义角色接口

  4. 确定承担这些角色的数据对象,定义数据类以及数据类的本地方法

好了,今天就聊这些,希望对你有所启发。

原创不易,如果你觉得这篇文章还不错,就「点赞」或者「在看」一下吧,鼓励我的创作 :)

也可以分享我的公众号名片给有需要的朋友们。

如果你有关于软件架构、分布式系统、产品、运营的困惑

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
辽篮夺冠之后,库珀发长文告别辽宁队,下赛季还回来吗,球迷期待

辽篮夺冠之后,库珀发长文告别辽宁队,下赛季还回来吗,球迷期待

最爱生活汇
2024-05-24 15:05:55
俄罗斯没想到,我们更没想到,如今的中国石油,成为石油遥遥领先

俄罗斯没想到,我们更没想到,如今的中国石油,成为石油遥遥领先

开姐樱花
2024-05-23 23:41:07
佘幼芝的离世,标志着佘氏家族长达390年的守墓史暂时画上了句号

佘幼芝的离世,标志着佘氏家族长达390年的守墓史暂时画上了句号

否知的否
2024-05-20 19:36:20
以色列总理,把公知和美国一下都干傻眼了

以色列总理,把公知和美国一下都干傻眼了

韬闻
2024-05-23 13:02:36
我军环台军演之际,7国在台发表联合声明,支持台湾参加世卫会议

我军环台军演之际,7国在台发表联合声明,支持台湾参加世卫会议

墨写东瀛话春秋
2024-05-24 20:18:31
小莫里斯:如果20年不在泡泡园区打比赛 我们肯定能夺冠

小莫里斯:如果20年不在泡泡园区打比赛 我们肯定能夺冠

直播吧
2024-05-25 03:33:13
网传某科室医师趁老公出差与主任在家约会,还要带上情趣内衣?

网传某科室医师趁老公出差与主任在家约会,还要带上情趣内衣?

一个岛岛
2024-05-24 22:54:20
暴雨+雷暴+大风!湖北即将迎来大范围降水

暴雨+雷暴+大风!湖北即将迎来大范围降水

鲁中晨报
2024-05-24 22:10:08
刘大锤爆料汪峰章子怡离婚原因:不是因为男方

刘大锤爆料汪峰章子怡离婚原因:不是因为男方

未来不可欺
2024-05-22 09:36:28
严格的空中管制,严重制约中国航空事业发展,中国机场数量只有美国的1/20

严格的空中管制,严重制约中国航空事业发展,中国机场数量只有美国的1/20

爆角追踪
2024-05-22 17:01:17
别了,保力新

别了,保力新

每日经济新闻
2024-05-24 19:05:13
凯特王妃最新图片曝光,脸部容颜尽毁,英王室的行为令人脊背发凉

凯特王妃最新图片曝光,脸部容颜尽毁,英王室的行为令人脊背发凉

据说说娱乐
2024-05-24 19:36:04
台湾地方县市长选举落幕,国民党赢了,民进党大败,蔡英文辞职

台湾地方县市长选举落幕,国民党赢了,民进党大败,蔡英文辞职

柠檬小7
2024-05-23 14:11:03
外交部领导班子调整!两位副部级领导履新!离任回国的他晋升“准副部”

外交部领导班子调整!两位副部级领导履新!离任回国的他晋升“准副部”

鲁中晨报
2024-05-11 15:31:06
向新帅看齐?萨拉赫晒全新造型,剪去标志性卷发平头出镜

向新帅看齐?萨拉赫晒全新造型,剪去标志性卷发平头出镜

圈里的甜橙子
2024-05-24 19:26:57
其实就是不敢打!台防务部门:解放军战机若靠近,要看有无敌意!

其实就是不敢打!台防务部门:解放军战机若靠近,要看有无敌意!

锋芒毕露
2024-03-20 17:28:15
19点30分!中国女排澳门站首秀,有望实现复仇,朱婷才是关键

19点30分!中国女排澳门站首秀,有望实现复仇,朱婷才是关键

跑者排球视角
2024-05-24 07:14:33
果不其然,这张图刷屏台媒丨湾区望海峡

果不其然,这张图刷屏台媒丨湾区望海峡

直新闻
2024-05-23 22:42:55
章子怡亮相电影宫,棕色旗袍显端庄,送友人中国特产获网友赞赏

章子怡亮相电影宫,棕色旗袍显端庄,送友人中国特产获网友赞赏

笑猫说说
2024-05-25 00:11:57
30秒|四川发布暴雨蓝色预警 雨下到哪儿?何时下?首席预报员来解读

30秒|四川发布暴雨蓝色预警 雨下到哪儿?何时下?首席预报员来解读

封面新闻
2024-05-24 18:42:06
2024-05-25 03:48:49
跨界架构师
跨界架构师
专注互联网技术、产品、运营
127文章数 454关注度
往期回顾 全部

游戏要闻

MSI复活赛来了?沙特电竞杯公布LOL直邀战队:BLG、TES、GEN和T1

头条要闻

媒体:解放军军演打赖清德个措手不及 美方反应出人意料

头条要闻

媒体:解放军军演打赖清德个措手不及 美方反应出人意料

体育要闻

阿兰,好久不见

娱乐要闻

霍启仁求婚成功,郭晶晶要有妯娌了

财经要闻

白重恩解读中国经济的3个关键问题

科技要闻

对话王小川:我们不跟进大模型价格战

汽车要闻

宝马M品牌上新 2024年在华推出近10款高性能车型

态度原创

本地
亲子
艺术
健康
房产

本地新闻

2024沈阳皇姑第二届半程马拉松

亲子要闻

女儿3岁了,父亲带她去打预防针,看孩子是啥反应

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

在中国,到底哪些人在吃“伟哥”?

房产要闻

超高性价比!仁恒长天云汀价格曝光!近500套房源一次砸出!

无障碍浏览 进入关怀版