天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

怪怪設計論閑談篇:職責與解耦的矛盾

正式討論之前,先看看這兩個問題:當我們的對象所涉及的操作不斷增加時,我們是否應該:Book.Save,Book.Serialize,Book.Method1,Book.Method2這樣一直增加下去?或者在某個垂直的邏輯中增加其它邏輯時,不斷的擴充Book.Save,要么象有的朋友說的那樣分離出去,再回調?但是Book.Save有理又有在,無論數據->對象,還是對象->數據,考慮到數據和對象經常一起變化,恢復對象的狀態這部分確實應該留在對象內部,同時,我也認可這本來就是對象的職責。

為了大家所謂的“低耦高聚”的目標,也為了保持職責的合理性,希望大家考慮一下,當Book沒有Save時,我們除了屬性賦值是不是就無路可走了?這就得那些沒包含在這次討論中的習慣性做法(比如平時對.NETFramework和ADO.NET的使用方式)包含近來,看看很多同志指出的美女走光問題,除了給美女一個電棍讓美女負擔起警察打擊偷窺者的職責,能不能通過換件裙子來解決。

我們平時用慣了IDataReader給對象賦值,所以很多人說的那種,從外部通過屬性賦值的情況就廣泛存在,比如CommunityServer。如果換一個方式呢? 把IDataReader直接交給Book,然后Book自己展開數據是不是好很多呢?于是有人又說了,這跟IDataReader耦合了,不利于移植等等。或者我根本沒用ADO,所以沒IDataReader。后者可以通過給自己的數據操作層實現IDataReader搞定;關鍵是前者,前者的非法性還表現在,把ADO的接口帶入了邏輯層;等等等等, 反正很多。那么為什么不能自己做一些類似IDataReader的接口,然后把ADO.NET包含的概念作為變化封裝出去呢? 

在保存數據的時候也一樣,不是把數據全部讀出來去保存,而是讓Book準備好需要保存的數據,總而言之歸它管的一分不落,然后實現或者返回出一個統一的接口里面全都是要持久的數據。至于如何跑回書架上,或者被賊給偷跑了,那是別人的事。畢竟某兄弟回復說的,今天加個Cache明天加個Log后天加個Permission最后數據庫都不用了的情況也確實有。這些都該Book負責嗎?不是說只添加不修改嗎?難道非得要求必須AOP? 我是Anders的忠實Fans,我不認為AOP解決了什么本質問題。怎么又說回職責問題了,總而言之,現在總不能有人說美女走光了吧。 

其實我們所說的方法,往往都有學習的對象,大家可以想想各種Control對于ViewState的使用,它其實就是這么一個玩意(關于Control如何使用和持久化ViewState的文章,園子里就有)。那么我們也可以這樣,數據就是數據,要什么屬性,而且IDataReader出來的不就是一砣類似字典的東西嗎?正好直接拿字符串和我們自己定義BL層與數據層之間對接的接口對應(與IDataReader不同的是,我們定義的接口是在邏輯層中使用的,除了象一個數據集,不包含任何和數據層相關的內容),覺得不過癮,把對應關系保存到配置文件里去。無論如何,希望讓對象自己負責恢復狀態,同時又不希望對象負責存取邏輯的矛盾,并非無法解決,ViewState的方式只是其中一種解決方法。

我們不妨再看看.NETFramework如何讓Serializer和你的對象在沒有聯系的情況下,通過增加一個翟通道,即不介入對象內部邏輯,又負擔了對象持久的:首先實現ISerializer這一接口,同時實現固定方法簽名的構造函數。保存數據時,他讓你自己打包然后從你的接口實現中獲得數據對象,恢復對象時,他調用你那個特別的構造函數,把數據字典還給你,然后讓你自己填充。拿Book來說,如果增加了需求,難道非得讓Book自己重新實現一個Book.Serialize方法嗎?鑒于一些朋友可能不清楚Serializer的工作機制,我借用一下MSDN的簡單例子,同時有所改動:

 

[Serializable]
public class MyObject : ISerializable 
{
    
public int N1 { getprivate set;} //公開取,私有存
    public int N2 { getinternal set;} //公開讀,內部存
    public String Str { getset;} //這些是VS 2008支持的寫法,不用自己定義私有變量了

    
public MyObject()
    {
    }

    
protected MyObject(SerializationInfo info, StreamingContext context) 
    {
        
//這個特殊的構造函數會被自動調用,如果是我們自己實現,就某Manager調用
        
//其實如果沒有復雜的構造函數初始化邏輯,比如給readonly變量賦值
        
//可以將SetObjectData直接實現于接口,由我們負責數據存取的部分來調用
        SetObjectData(info);
    }

    
protected virtual void SetObjectData(SerializationInfo info)
    {
        N1
= info.GetInt32("i");  //由對象自己將數據字典展開
        N2 = info.GetInt32("j");  //還原對象狀態
        Str = info.GetString("k"); //這樣就可以把跟對象無關的存儲邏輯外包出去
    }

    [SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter
=true)]
    
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(
"i", N1);//info可以理解為Serializer定義的數據字典格式
        info.AddValue("j", N2);//這相當于持久化的概念進入了BL層
        info.AddValue("k", Str);//所以當我們實現時,應該根據業務邏輯定義自己的數據字典
    }
}

Serializer:
BinaryFormatter formatter 
= new BinaryFormatter();

保存至fs:
formatter.Serialize(fs, a1);

從fs讀取:
formatter.Deserialize(fs);

it知識庫怪怪設計論閑談篇:職責與解耦的矛盾,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 做暧暧免费30秒体验 | 先锋影音 av| 久久久免费观成人影院 | 国产产一区二区三区久久毛片国语 | 午夜福利08550 | 最新在线黄色网址 | 90后性爱视频 | 久久综合给合久久狠狠狠… | 江苏电台在线收听 | 久久99精品国产免费观看 | 97人妻在线公开视频在线观看 | 狠狠综合久久综合88亚洲 | 99视频这里只有精品国产 | 成人综合在线视频免费观看完整版 | 91久久综合精品国产丝袜长腿 | 欧美成人免费一区二区三区不卡 | 99视频导航 | 秋霞电影网午夜鲁丝片 | 国产视频精品免费 | 美女露100%全身无遮挡 | 九九热在线视频精品店 | 伊伊人成亚洲综合人网 | 无人视频在线观看免费播放影院 | 欧美丰满熟妇BBB久久久 | 超碰高清熟女一区二区 | 欧美一区二区激情视频 | 九九热精品在线观看 | 久久亚洲人成国产精品 | qvod伦理片| 亚洲国产精品高清在线 | 狠狠撩色姣姣综合久久 | 国产欧美另类久久久精品免费 | 欧美国产在线一区 | 亚洲精品久久久久久偷窥 | 国产手机在线视频 | 婷婷六月激情综合一区 | 久久嫩草影院网站 | 国产AV精品国语对白国产 | 麻豆成人久久精品二区三区网站 | 久久精品国产久精国产果冻传媒 | 无码不卡中文字幕在线观看 |