天天看點

架構模式資料源模式之:表資料入口(Table Data Gateway)、行資料入口(Row Data Gateway)、活動記錄(Active Record)

一:表資料入口(Table Data Gateway)

表資料入口提供了用于通路單個表或者視圖(也包含了聯表查詢)的所有SQL,通常一個表一個類。其它代碼通過它來實作對資料庫的互動。基于這個特點,表資料入口和事務腳本代碼以及表子產品結合的很好。

在查詢時候,表資料接口可以傳回資料集 或者 DTO 或者 DTO清單。在 事務腳本 代碼中已經闡述過了 DTO 以及 DTO 的清單這種形式。但是使用 DTO 這種形式,帶來的一個問題是:到處衍生的 DTO,那麼,如何減少到處衍生的 DTO 的,見這裡《》。

在傳統做法中,表資料入口和領域模型不一起使用,使用領域模型,一般使用資料映射器。

表資料入口的代碼到處都是,如:

    public class UserDal : SqlServerDal<User>      {          public override IList<User> GetList()          {              string sql = "select * from [EL_Organization].[User] where state=1";              var ds = SqlHelper.ExecuteDataset(CommandType.Text, sql);             IList<User> oblist = new List<User>();              foreach (DataRow row in ds.Tables[0].Rows)              {                  oblist.Add(new User{ Id = (string)row["Id"], Name = (string)row["Name"] });              }             return oblist;          }          public override User FindOne(User t){ return null;}          public override void Insert(User model) {}          public override void Update(User t){}         public override void Delete(User t){}      }     public class User          public string Id;          public string Name; 

二:行資料入口(Row Data Gateway)

行資料入口,則表中的一行記錄存在一個對象。

    public class UserDal          public void Load(DataSet ds)              //根據 ds 得到自身,而這個 ds 有可能是從 UserFinderDal 得到的          public void Insert()              string sql = @"INSERT INTO [EL_Organization].[User] ('Id', 'Name') VALUES (" + this.Id + "," + this.Name + ")";              var ds = SqlHelper.Execute(CommandType.Text, sql);          public void Update()              // update this;          }         public void Delete()              // delete this;      public class UserFinderDal          public UserDal FindOne(string id)              string sql = "select * from [EL_Organization].[User] where id=" + id;                  return new UserDal {Id = (string)row["Id"], Name = (string)row["Name"]}; ;              }              return null;          public List<UserDal> FindList(string name) 

可以看到,和表資料庫入口比,查詢資料庫中的資料,表資料庫入口隻要一個類就可以了,而行資料入口則需要兩個類,自身也被用做資料庫實體,但是負責自身的 update insert delete,而要查詢自身和集合或者是操作集合,則需要另外一個類來完成。

二:活動記錄(Active Record)

活動記錄 與 行資料入口 很類似。二者的差别是 行資料入口 隻有資料庫通路而 活動記錄 是即有資料庫通路又有領域邏輯。在 行資料入口 中,我們一般使用兩個類,而在活動記錄中,一般則無此限制,通常情況下,一個類可能會顯得更清爽。

領域模型,一般和 活動記錄 或者 資料映射器 協作。

在軟體開發中,初級的做法是:事務腳本;

比較進階一點的做法是:活動記錄。一般,當發現事務腳本的代碼已經複雜到難以維護的時候,則可以逐漸建立活動記錄,然後慢慢為它們添加行為,即:把表包裝成為活動記錄,然後添加領域邏輯。

最複雜而進階的做法是:領域模型。

從以上的描述中,我們很容易知道如何修改本文中的 表資料入口 或者 行資料入口 的代碼,繼而讓它成為 活動記錄 的。

    public class UserActiveRecord          public UserActiveRecord FindOne(string id)                  return new UserActiveRecord {Id = (string)row["Id"], Name = (string)row["Name"]}; ;          public List<UserActiveRecord> FindList(string name)          public void SomeOtherLogic() 

從上面的代碼來看,活動記錄這種模式不在 業務邏輯層 和 資料通路層,因為它們是一體的。而事務腳本 或者 表資料入口 和 行資料入口,多多少少可以存在兩層的概念。

本文轉自最課程陸敏技部落格園部落格,原文連結:http://www.cnblogs.com/luminji/p/3734225.html,如需轉載請自行聯系原作者