备注
之前把DCI的Role和四色原型的Role给弄混了,本文也不会比较这两种Role的区别(后面有机会再说),这里简单的记录一下对DCI的理解。
参考文章:。
什么是DCI?
Context 选择 Data,让 Data 扮演 Role 执行 Interaction。
Data
用户模型(只包含数据和本地方法)。
如:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DCIStudy.V7 8 { 9 public partial class People10 {11 public string Name { get; set; }12 13 public TRole Act()14 where TRole : class15 {16 return this as TRole;17 }18 }19 }
Context
面向用例设设计,职责为:选择对象,让对象扮演角色,让角色执行交互。
如:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DCIStudy.V7.Company 8 { 9 public class CompanyContext10 {11 public void Execute()12 {13 //选择对象。14 var steven = new People { Name = "Steven" };15 16 //扮演角色。17 var developer = steven.Act();18 19 //执行交互。20 developer.Coding();21 }22 }23 }
Interaction
角色的行为驱动用例的执行。
如:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 using DCIStudy.V7.Company; 8 9 namespace DCIStudy.V710 {11 public partial class People : IDeveloper12 {13 void IDeveloper.Coding()14 {15 Console.WriteLine(string.Format("{0},快乐的编程中!",this.Name));16 }17 }18 }
如何将Role注入到Data中?
开发期注入
字节码增强
下文的语法是AspectJ吗?我没有验证,有懂的朋友给我留言,我感觉字节码增强是可以实现的。
Mixin
。
Trait
Trait本质上是一种Mixin的实现,Scala和Php5.4在语法级别支持了trait。
。
Template
。
T4 + 部分类 + 显式接口实现 + 扩展类型,C#专用
后面会给出示例,因为T4 + 扩展类型都是为了复用的,后文只给出显示接口实现 + 部分类的代码,如果有复用需求,可以引入T4 + 扩展类型。
运行期注入
Mixin
Mixin也分开发期间Mixin和运行期间Mixin。
凡是支持OpenClass的语言都支持运行期间Mixin,如:Ruby、Python和Javascript。OpenClass的本质是运行期间可以修改类型系统,也叫“动态类型”,像Php这种静态类型语言就没有这个特性,虽然Php是弱类型和解释执行的。
(重点看Ruby)。
动态代理
。
为什么要用DCI?
如果将DCI作为一种编程模式或设计模式的话,我是比较认可的,作为一种架构模式,还有待考量,等有机会用一下再做评价。
DCI在C#种的两种实现
第一种:显式接口实现 + 部分类
项目结构
代码(给出一个上下文的代码)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DCIStudy.V7.Home 8 { 9 public class HomeContext10 {11 public void Execute()12 {13 //选择对象。14 var steven = new People { Name = "Steven" };15 16 //扮演角色。17 var player = steven.Act();18 19 //执行交互。20 player.Play();21 }22 }23 }24 25 using System;26 using System.Collections.Generic;27 using System.Linq;28 using System.Text;29 using System.Threading.Tasks;30 31 namespace DCIStudy.V7.Home32 {33 public interface IPlayer34 {35 void Play();36 }37 }38 39 using System;40 using System.Collections.Generic;41 using System.Linq;42 using System.Text;43 using System.Threading.Tasks;44 45 using DCIStudy.V7.Home;46 47 namespace DCIStudy.V748 {49 public partial class People : IPlayer50 {51 void IPlayer.Play()52 {53 Console.WriteLine(string.Format("{0},疯狂的游戏中!",this.Name));54 }55 }56 }57 58 using System;59 using System.Collections.Generic;60 using System.Linq;61 using System.Text;62 using System.Threading.Tasks;63 64 namespace DCIStudy.V765 {66 public partial class People67 {68 public string Name { get; set; }69 70 public TRole Act ()71 where TRole : class72 {73 return this as TRole;74 }75 }76 }
第二种实现:组合
项目结构
代码(给出一个上下文的代码)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DCIStudy.V8.Company 8 { 9 public class CompanyContext10 {11 public void Execute()12 {13 //选择对象。14 var steven = new People { Name = "Steven" };15 16 //扮演角色。17 var developer = steven.Act();18 19 //执行交互。20 developer.Coding();21 }22 }23 }24 25 using System;26 using System.Collections.Generic;27 using System.Linq;28 using System.Text;29 using System.Threading.Tasks;30 31 namespace DCIStudy.V8.Company32 {33 public class CompanyContext34 {35 public void Execute()36 {37 //选择对象。38 var steven = new People { Name = "Steven" };39 40 //扮演角色。41 var developer = steven.Act ();42 43 //执行交互。44 developer.Coding();45 }46 }47 }48 49 using System;50 using System.Collections.Generic;51 using System.Linq;52 using System.Text;53 using System.Threading.Tasks;54 55 namespace DCIStudy.V856 {57 public class People58 {59 public string Name { get; set; }60 61 public TRole Act ()62 where TRole : class63 {64 var role = Activator.CreateInstance ();65 66 (role as dynamic).People = this;67 68 return role;69 }70 }71 }
备注
相对于DDD,DCI给出的模式显得过于泛化了,如:分层、分区(BondedContext)、每个层有哪些元素、如何交互等,DCI、四色原型和DDD应该可以以某种形式融合,有待慢慢思考。