我在 前一篇文章中提到ActiveRecord, 有人在回復(fù)中問(wèn)什么是ActiveRecord. 說(shuō)實(shí)話,從去年開(kāi)始用SubSonic, 我就一直有點(diǎn)困惑, 什么是ActiveRecord, 什么不是ActiveRecord, 以及應(yīng)該怎么樣使用它才對(duì). 把我的一些想法寫(xiě)下來(lái), 希望能和大家交流. 歡迎拍磚. ActiveRecord是什么: 1. 每一個(gè)數(shù)據(jù)庫(kù)表對(duì)應(yīng)創(chuàng)建一個(gè)類(lèi).類(lèi)的每一個(gè)對(duì)象實(shí)例對(duì)應(yīng)于數(shù)據(jù)庫(kù)中表的一行記錄; 通常表的每個(gè)字段在類(lèi)中都有相應(yīng)的Field; 2. ActiveRecord同時(shí)負(fù)責(zé)把自己持久化. 在ActiveRecord中封裝了對(duì)數(shù)據(jù)庫(kù)的訪問(wèn), 即CRUD; 3. ActiveRecord是一種領(lǐng)域模型(Domain Model), 封裝了部分業(yè)務(wù)邏輯; ActiveRecord不是什么: 1. Row Data Gateway Row Data Gateway模式中每個(gè)對(duì)象也封裝了數(shù)據(jù)庫(kù)記錄的狀態(tài)和持久化到數(shù)據(jù)庫(kù)的訪問(wèn)方法; 這兩個(gè)有時(shí)候很難區(qū)分. 細(xì)微的區(qū)別在于Row Data Gateway不封裝任何業(yè)務(wù)邏輯; 2. TableGateway TableGateway是一種數(shù)據(jù)訪問(wèn)模式, 對(duì)每個(gè)表有一個(gè)類(lèi), 類(lèi)的方法封裝了對(duì)單個(gè)表的數(shù)據(jù)操作, 如CRUD; 方法的接受表字段的值作為參數(shù); 比如說(shuō)對(duì)表Person有DAOPerson, 有以下方法: int Create(string name, bool isMale) DataSet Find(int personId) void Delete(int personId) void Update(int personId, string name, bool isMale) 微軟的很多代碼示例中使用了此模式; ActiveRecord的區(qū)別在于ActiveRecord的對(duì)象中保持了記錄的值, 是有狀態(tài)的, 而TableGateway是沒(méi)有狀態(tài)的, 只是一系列數(shù)據(jù)庫(kù)訪問(wèn)方法的集合; 3. Table Module Table Module是一種領(lǐng)域邏輯模式, 一個(gè)類(lèi)對(duì)應(yīng)于數(shù)據(jù)庫(kù)中的一個(gè)表; Table Module通常和Table Gateway合作, 前者負(fù)責(zé)基本的業(yè)務(wù)邏輯, 后者負(fù)責(zé)數(shù)據(jù)庫(kù)訪問(wèn), 以達(dá)到邏輯層和持久化層的隔離; 微軟的實(shí)例代碼經(jīng)常使用這兩者, 如對(duì)表Person, 通常會(huì)定義兩個(gè)類(lèi), PersonBL和PersonDB, 在PersonBL中處理驗(yàn)證等邏輯, 并調(diào)用PersonDB訪問(wèn)數(shù)據(jù)庫(kù), 層間調(diào)用使用DataSet或自定義數(shù)據(jù)傳輸對(duì)象傳輸數(shù)據(jù) 在業(yè)務(wù)邏輯比較簡(jiǎn)單并且有和表的一一對(duì)應(yīng)時(shí), ActiveRecord相對(duì)來(lái)說(shuō)更簡(jiǎn)單, 因?yàn)樗谝粋€(gè)類(lèi)中包括了業(yè)務(wù)邏輯對(duì)象和數(shù)據(jù)訪問(wèn), 而且不需要數(shù)據(jù)傳輸對(duì)象, 減少了維護(hù)的工作量; 和Table Module比較起來(lái), ActiveRecord與數(shù)據(jù)庫(kù)耦合更緊; ActiveRecord適用于: 1. 業(yè)務(wù)邏輯比較簡(jiǎn)單;當(dāng)你的類(lèi)基本上和數(shù)據(jù)庫(kù)中的表一一對(duì)應(yīng)時(shí), ActiveRecord是非常方便的, 即你的業(yè)務(wù)邏輯大多數(shù)是對(duì)單表操作; 2. 當(dāng)發(fā)生跨表的操作時(shí), 往往會(huì)配合使用事務(wù)腳本(Transaction Script), 把跨表事務(wù)提升到事務(wù)腳本中; 3. ActiveRecord最大優(yōu)點(diǎn)是簡(jiǎn)單, 直觀; 一個(gè)類(lèi)就包括了數(shù)據(jù)訪問(wèn)和業(yè)務(wù)邏輯. 如果配合代碼生成器使用就更方便了; 4. 這些優(yōu)點(diǎn)使ActiveRecord特別適合web快速開(kāi)發(fā), 而正是快速開(kāi)發(fā)框架ROR采用了ActiveRecord, 并且很多類(lèi)ROR框架如Castle的紛紛效仿才使ActiveRecord重新進(jìn)入大家視線; 我想這也是為什么Martin Fowler在PoEAA中早就提出了這個(gè)模式, 但是直到最近兩三年ActiveRecord才熱起來(lái)可能就是這個(gè)原因; ActiveRecord不適合于 1. ActiveRecord雖然有業(yè)務(wù)邏輯, 但基本上都是基于單表的. 跨表邏輯一般會(huì)放到當(dāng)發(fā)生跨表的操作時(shí), 往往會(huì)配合使用事務(wù)腳本(Transaction Script)中. 如果對(duì)象間的關(guān)聯(lián)越來(lái)越多, 你的事務(wù)腳本越來(lái)越龐大, 重復(fù)的代碼越來(lái)越多, 你就要考慮Domain Model + O/R Mapper了; 2. ActiveRecord保存了數(shù)據(jù), 使它有時(shí)候看上去像數(shù)據(jù)傳輸對(duì)象(DTO). 但是ActiveRecord有數(shù)據(jù)庫(kù)訪問(wèn)能力, 不要把它當(dāng)DTO用. 尤其在跨越進(jìn)程邊界調(diào)用的時(shí)候, 不能傳遞ActiveRecord對(duì)象; |
|