備注
之前把DCI的Role和四色原型的Role給弄混了,本文也不會比較這兩種Role的區別(后面有機會再說),這里簡單的記錄一下對DCI的理解。
參考文章:http://www.cnblogs.com/happyframework/p/3302238.html。
什么是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 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嗎?我沒有驗證,有懂的朋友給我留言,我感覺字節碼增強是可以實現的。
Mixin
http://www.cnblogs.com/happyframework/archive/2013/04/25/3040461.html。
Trait
Trait本質上是一種Mixin的實現,Scala和Php5.4在語法級別支持了trait。
http://php.net/manual/en/language.oop5.traits.php。
Template
http://www.cnblogs.com/stephen-liu74/archive/2012/08/12/2635583.html。
T4 + 部分類 + 顯式接口實現 + 擴展類型,C#專用
后面會給出示例,因為T4 + 擴展類型都是為了復用的,后文只給出顯示接口實現 + 部分類的代碼,如果有復用需求,可以引入T4 + 擴展類型。
運行期注入
Mixin
Mixin也分開發期間Mixin和運行期間Mixin。
凡是支持OpenClass的語言都支持運行期間Mixin,如:Ruby、Python和Javascript。OpenClass的本質是運行期間可以修改類型系統,也叫“動態類型”,像Php這種靜態類型語言就沒有這個特性,雖然Php是弱類型和解釋執行的。
http://www.cnblogs.com/happyframework/archive/2013/04/25/3040461.html(重點看Ruby)。
動態代理
http://www.cnblogs.com/happyframework/p/3295853.html
為什么要用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 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 }
第二種實現:組合
項目結構
代碼(給出一個上下文的代碼)
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應該可以以某種形式融合,有待慢慢思考。