ghost60 / blog

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

The DCI Architectur

原文:https://github.com/dt-fe/weekly/blob/v2/014.%E7%B2%BE%E8%AF%BB%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1%E4%B9%8B%20DCI.md

疑问:面向接口编程,面向切面编程

DCI 是数据 Data 场景 Context 交互 Interactions 简称, 重点是关注 数据的不同场景的交互行为, 是面向对象系统 状态和行为的一种范式设计

DCI 之所以被提出,是因为传统 mvc 代码,在越来越丰富的交互需求中变得越来越难读。有人会觉得,复杂的需求 mvc 也可以 cover 住,诚然如此,但很少有人能只读一遍源码就能理解程序处理了哪些事情,这是因为人类思维与 mvc 的传统程序设计**存在鸿沟,我们需要脑补内容很多,才会觉得难度。

现在仍有大量程序使用面向对象的**表达交互行为,当我们把所有对象之间的关联记录在脑海中时,可能对象之间交互行为会比较清楚,但任无法轻松理解,因为对象的封装会导致内聚性不断增加,交互逻辑会在不同对象之间跳转,对象之间的嵌套关系在复杂系统中无疑是一个理解负担。

DCI 尝试从人类思维角度出发,举一个例子:为什么在看电影时会轻轻松松的理解故事主线呢?回想一下我们看电影的过程,看到一个画面时,我们会思考三件事:

画面里有什么人或物? 人或物发生了什么行为、交互? 现在在哪?厨房?太空舱?或者原始森林? 很快把这三件事弄清楚,我们就能快速理解当前场景的逻辑,并且轻松理解该场景继续发生的状况,即便是盗梦空间这种烧脑的电影,当我们搞清楚这三个问题后,就算街道发生了 180 度扭曲,也不会存在理解障碍,反而可以吃着爆米花享受,直到切换到下一个场景为止。

当我们把街道扭曲 180 度的能力放在街道对象上时,理解就变的复杂了:这个函数什么时候被调用?为什么不好好承载车辆而自己发生扭曲?这就像电影开始时,把电影里播放的所有关于街道的状态都走马灯过一遍:我们看到街道通过了车辆、又卷曲、又发生了爆炸,实在觉得莫名其妙。

理解代码也是如此,当交互行为复杂时,把交互和场景分别抽象出来,以场景为切入点交互数据。

就是把数据与交互分开,额外增加了场景,交互属于场景,获取数据进行交互.

结合 DCI 设想开发的过程中使用到一些设计方法和原则

举个例子: 在一个 BI 系统中, 在业务的发展中, 这个系统使用到了多套的 底层图表库,比如: Echarts, G2,Recharts, FusionChart; 等等;

那么问题来了,

如何去同时支持 这些底层库, 并且达到很容易切换的一个效果? 如何去面向未来的考虑 将来接入更多类型的图表? 如何去考虑扩展业务 对图表的日益增强的业务功能(如: 行列转换、智能格式化 等等) 带着这些问题, 我们再来看下 DCI 给我们的启示, 我们来试试看相应的解法:

图表的模型数据就是 数据 Data , 我们可以把[日益增强的业务功能] 认为是各个场景交互 Interactions;

接入更多类型的图表咋么搞? 不同类型的图表其实是图表数据模型的转换,我们也可以把这些转换的行为过程作为一个个的切片(Aspect),每个切片都是独立的, 松耦合的 ;

接入多套底层库怎么搞? 每个图形库的 build 方法,render 方法 , resize 方法,repaint 方法 都不一样 ,怎么搞 ? 我们可以使用 DCI 提到的元编程- 我们在这里理解为面向接口编程, 我们分装一层 统一的接口; 利用面向接口的父类引用指向子类对象 我们就可以很方便的 接入更多的 implement 接入更多的图形库(当然,一个系统统一一套是最好的);

About