淺談C#中的延遲加載(3)——還原模型的業務規則

來源: youguanbumen.net  發布時間: 2011-02-14 23:04  閱讀: 1621 次  推薦: 0   原文鏈接   [收藏]  
摘要:沿用前面兩篇文章的例子,作者對“文章”實體類做了點修改。

  上一篇文章講到把實體類中需要實現延遲加載的屬性聲明為virtual,然后繼承實體類做一個子類,在子類里面實現該屬性,配合使用委托來實現比較完美的延遲加載(原本的模型層依舊保持在最底層用于貫穿三層結構,同時又可以實現在實體類的屬性里面訪問到比他高層的數據訪問層)。文章的最后依舊出現杯具,原因是在對模型的屬性實現延遲加載之前,這個屬性可能由于我們業務的需要,它并不單單是作為一個存儲和讀取的功能使用,而是在其get或者set的訪問器中都包含這或許復雜或許簡單的邏輯代碼。

  舉例:考慮一下這個情景,我們有一個叫做任務單的實體類,其中有兩個屬性,一個叫做任務名,一個叫做發布時間,現在有這樣的業務規定,任務名稱可以為空,但如果任務名稱為空的話我們要讀取發布時間生成一個任務名來代替掉這個空值(例如叫做Issue20110120191345),當然這個例子有點牽強,主要是我想不出什么很具體的實例,但是在實際開發中這種情況肯定是有的并且其中的邏輯代碼有可能復雜到你難以想象。

  沿用前面兩篇文章的例子,我模擬了這一現象,對文章實體類做了點修改,增加了一個名為GetCategoryRecord的字符串型屬性,它的作用基本上可以從字面上看出來,叫做Category屬性get訪問器調用記錄。于是文章類(基類)修改如下:

 
c#代碼

namespace Model
{

// 文章實體類
public class Article
{

public int ArticleID { get; set; }
public string Title { get; set; }
public string Cotnent{ get; set; }
public DateTime CreateTime { get; set; }
public int CategoryID { get; set; }
/// <summary>
/// 所屬分類
/// </summary>
protected Model.ArticleCategory _category;
/// <summary>
/// 所屬分類
/// </summary>
public virtual Model.ArticleCategory Category
{

get
{
GetCategoryRecord
+= "獲取分類;";
return _category;
}
}

/// <summary>
/// Category屬性get訪問器調用記錄
/// </summary>
public string GetCategoryRecord { get; set; }
}
}

  這里我們關心那兩個有寫注釋的屬性,并且出現了一個保護字段_category(這個尤其重要,起到和子類的聯通作用)。可以看到現在有這樣的業務規則了:Category屬性被get一次就會往GetCategoryRecord屬性中做點記錄。于是我們在設計代碼的時候立刻會想到要是繼承Model.Article類的基類要是重寫這個屬性的話勢必要保持這個業務不變,否則在實現延遲加載之后肯定會丟掉一些之前設計好的業務邏輯了。修改繼承它的子類如下:

 
c#代碼

namespace DModel
{

/// <summary>
/// 文章
/// </summary>
public class Article : Model.Article
{

/// <summary>
/// 所屬分類
/// </summary>
public override Model.ArticleCategory Category
{

get
{
if (base._category == null)
{

if (CategoryLazyLoader != null)
{

base._category = CategoryLazyLoader(CategoryID);
}

else
{
base._category = null;
}
}

return base.Category;
}
}

/// <summary>
/// 文章分類延時加載器(委托)
/// </summary>
public Func<int, Model.ArticleCategory> CategoryLazyLoader { get; set; }
}
}

  這里可以看到DModel.Article類的Category屬性中對基類的保護字段base._cateogry進行了操作,最后返回的是基類Category。粗看起來似乎有點亂,但是理清一下思路其實如下:基類的Category屬性通過返回_category字段的方式返回值,也就是說數據是存在_category字段而不是屬性中,但是_category字段怎么才會有值呢,那就是在子類里面通過調用委托拿來的,而這個屬性在子類里面不是直接返回的,而是調用基類來返回,這樣一來,調用到子類的Category屬性的get訪問器的時候,先對基類的_categoty字段賦值,然后調用基類的Category屬性執行了一些邏輯代碼,最后成功地把(已經被賦值的)基類的_categoty字段給返回去。而這一切都是在前面我們實現好的延遲加載的基礎上完成的。總結成幾個字就是:子類負責延時加載,基類賦值數據存儲和返回!呵呵,是不是覺得很簡單呢。

這里可以看到DModel.Article類的Category屬性中對基類的保護字段base._cateogry進行了操作,最后返回的是基類Category。粗看起來似乎有點亂,但是理清一下思路其實如下:
基類的Category屬性通過返回_category字段的方式返回值,也就是說數據是存在_category字段而不是屬性中,但是_category字段怎么才會有值呢,那就是在子類
里面通過調用委托拿來的,而這個屬性在子類里面不是直接返回的,而是調用基類來返回,這樣一來,調用到子類的Category屬性的get訪問器的時候,先對_categoty字段賦值,然后調用基類的Category屬性實現了一些邏輯代碼,最后成功地把(已經被賦值的)_categoty字段給返回去。而這一切都是在前面我們實現好的延遲加載的基礎上完成的。呵呵,是不是覺得很簡單呢^^
這里可以看到DModel.Article類的Category屬性中對基類的保護字段base._cateogry進行了操作,最后返回的是基類Category。粗看起來似乎有點亂,但是理清一下思路其實如下:
基類的Category屬性通過返回_category字段的方式返回值,也就是說數據是存在_category字段而不是屬性中,但是_category字段怎么才會有值呢,那就是在子類
里面通過調用委托拿來的,而這個屬性在子類里面不是直接返回的,而是調用基類來返回,這樣一來,調用到子類的Category屬性的get訪問器的時候,先對_categoty字段賦值,然后調用基類的Category屬性實現了一些邏輯代碼,最后成功地把(已經被賦值的)_categoty字段給返回去。而這一切都是在前面我們實現好的延遲加載的基礎上完成的。呵呵,是不是覺得很簡單呢^^

  其實這一篇講的情況不是針對延遲加載這個技術來講的,在我們的開發過程中經常會遇到這種實現了業務代碼的實體類屬性,擁有這種屬性的模型通常被叫做充血模型,如果模型的屬性都是簡單的get和set的話通常叫做貧血模型(當然可能有其他叫法 哈~)。這篇文章是在沒啥內容,算是對前兩篇文章的一個補充吧,希望沒有浪費你的時間哈^_^。

0
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()