淺談C#中的消極式載入(3)——還原模型的商務規則 )

來源:互聯網
上載者:User

啊~~最近的業餘時間都用在修改部落格上面了,主要是這段時間在網站的留言板上發現很多外國的垃圾廣告,於是做了個“IP黑名單”的功能,留言和文章評論也都加了驗證碼,順便把背景代碼整理了一下,希望新加的驗證碼不會對大家留言和發評論造成不便!

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

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

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

c#代碼?
12345678910111213141516171819202122232425262728293031 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#代碼?
12345678910111213141516171819202122232425262728293031323334 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的話通常叫做“貧血模型”(當然可能有其他叫法 哈~)。這篇文章是在沒啥內容,算是對前兩篇文章的一個補充吧,希望沒有浪費你的時間哈^_^。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.