DCI:DCI学习总结

备注

之前把DCI的Role和四色原型的Role给弄混了,本文也不会比较这两种Role的区别(后面有机会再说),这里简单的记录一下对DCI的理解。

什么是DCI?

Context 选择 Data,让 Data  扮演 Role 执行 Interaction。

DCI:DCI学习总结_分享

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 People
10     {
11         public string Name { get; set; }
12 
13         public TRole Act<TRole>()
14             where TRole : class
15         {
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 CompanyContext
10     {
11         public void Execute()
12         {
13             //选择对象。
14             var steven = new People { Name = "Steven" };
15 
16             //扮演角色。
17             var developer = steven.Act<IDeveloper>();
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.V7
10 {
11     public partial class People : IDeveloper
12     {
13         void IDeveloper.Coding()
14         {
15             Console.WriteLine(string.Format("{0},快乐的编程中!",this.Name));
16         }
17     }
18 }
如何将Role注入到Data中?

开发期注入

字节码增强

下文的语法是AspectJ吗?我没有验证,有懂的朋友给我留言,我感觉字节码增强是可以实现的。

DCI:DCI学习总结_分享_02

Mixin

Trait

Trait本质上是一种Mixin的实现,Scala和Php5.4在语法级别支持了trait。

http://php.net/manual/en/language.oop5.traits.php。

Template

T4 + 部分类 + 显式接口实现 + 扩展类型,C#专用

后面会给出示例,因为T4 + 扩展类型都是为了复用的,后文只给出显示接口实现 + 部分类的代码,如果有复用需求,可以引入T4 + 扩展类型。

运行期注入

Mixin

Mixin也分开发期间Mixin和运行期间Mixin。

凡是支持OpenClass的语言都支持运行期间Mixin,如:Ruby、Python和Javascript。OpenClass的本质是运行期间可以修改类型系统,也叫“动态类型”,像Php这种静态类型语言就没有这个特性,虽然Php是弱类型和解释执行的。

动态代理

http://qi4j.org/。

为什么要用DCI?

如果将DCI作为一种编程模式或设计模式的话,我是比较认可的,作为一种架构模式,还有待考量,等有机会用一下再做评价。

DCI在C#种的两种实现

第一种:显式接口实现 + 部分类

项目结构

DCI:DCI学习总结_分享_03

代码(给出一个上下文的代码)

 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 HomeContext
10     {
11         public void Execute()
12         {
13             //选择对象。
14             var steven = new People { Name = "Steven" };
15 
16             //扮演角色。
17             var player = steven.Act<IPlayer>();
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.Home
32 {
33     public interface IPlayer
34     {
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.V7
48 {
49     public partial class People : IPlayer
50     {
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.V7
65 {
66     public partial class People
67     {
68         public string Name { get; set; }
69 
70         public TRole Act<TRole>()
71             where TRole : class
72         {
73             return this as TRole;
74         }
75     }
76 }

第二种实现:组合

项目结构

DCI:DCI学习总结_分享_04

代码(给出一个上下文的代码)

 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 CompanyContext
10     {
11         public void Execute()
12         {
13             //选择对象。
14             var steven = new People { Name = "Steven" };
15 
16             //扮演角色。
17             var developer = steven.Act<Developer>();
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.Company
32 {
33     public class CompanyContext
34     {
35         public void Execute()
36         {
37             //选择对象。
38             var steven = new People { Name = "Steven" };
39 
40             //扮演角色。
41             var developer = steven.Act<Developer>();
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.V8
56 {
57     public class People
58     {
59         public string Name { get; set; }
60 
61         public TRole Act<TRole>()
62             where TRole : class
63         {
64             var role = Activator.CreateInstance<TRole>();
65 
66             (role as dynamic).People = this;
67 
68             return role;
69         }
70     }
71 }
备注

相对于DDD,DCI给出的模式显得过于泛化了,如:分层、分区(BondedContext)、每个层有哪些元素、如何交互等,DCI、四色原型和DDD应该可以以某种形式融合,有待慢慢思考。

 

框架地址:http://happy.codeplex.com