這裡的數據指的大概就是字段(貌似這章有些東西也是過時了,因為現在的.NET已經發展了很久了,包括Java也是)
1、自封裝字段(其實就是屬性啦,過時了)
修改點:直接訪問字段,但是與字段間的耦合關系逐漸變得笨拙
做法:為這個字段建立一個取值/設值函數,並且只以這些函數來訪問數據
好吧,現在明白屬性是怎麼來的了嗎,就是因為這個原因,所以有的人會干脆和你說,你不要寫公共字段,直接寫公共屬性。
因為公共字段能做的公共屬性都能做,不能做的公共屬性也能做。
public string 我叫公共屬性 { get; set; }
多寫個這東西好用多了,以後萬一有個什麼反射的需要,也簡單多了,舉手之勞,所以忘記還有公共字段這回事吧。
2、以對象取代字段
修改點:你有一個字段,需要與其它數據和行為一起使用才有意義
做法:用對象取代字段
簡單地說,你玩過DateTime這個類嗎,就是系統的類,其實就是對數據的一個封裝啊。
如果沒有這個東西,那麼你是不是要用年,月,日(就算沒有時分秒吧),三個字段來表示。搞的多了自然就像自己封裝一個Date類,哪天又多了個按格式輸出的要求,是不是要再寫個格式化函數
所以那麼就把這些好基友都放在一起好了,於是DateTime就成了基友之家。(然而我們需要更多的DateTime樣的基友之家)
3、將值對象改為引用對象
修改點:你從一個類衍生出許多彼此相等的實例,希望將它們替換為同一個對象
做法:將這個值對象變為引用對象
簡單地說,這裡所謂的值對象是指DateTime這種對象,即可以建立很多次,純數據的傳遞,而所謂的引用對象是指緩存的東西,比如淘寶界面的分類數據,因為所有人看到的分類都是一樣的,那麼我們不需要每次都從數據庫取值
緩存一下就好,不需要每次New一個分類對象,然後調用查詢函數,而是去找緩存去看是否有了緩存,有了緩存,那麼就調用,沒有緩存那麼就再從數據庫裡面取值。只要緩存一更改,大家看到的分類就都更改了。
好了,就是這麼個意思
其中為了適應也許引用對象會根據不同的類型創建一個不同的對象,(就像有個牆類,上節課Troy教小朋友們如何搬磚砌牆,所以新建正常的牆的對象,這節課話題換了,Troy教小朋友們碼長城,於是就新建一個長城對象)
當涉及到切換子類的時候,可以用這種方法使得客戶端調用的時候不需要知道還有長城這個類,只需要用牆類裡的工廠函數就好了,當然也許你下次還得搞個扛水泥去搞個水泥牆的類,那麼在 工廠函數裡再加就好了。
所以提到的一個重構方法:
將構造函數改為調用工廠函數,即
public class Wall{ public Wall(string length){ //啦啦啦 } }
改為
public class Wall{ public static Wall Create(string type){ if (type=="Great"){ return new GreatWall("一萬裡"); } else{ return new Wall("一米"); } } protected Wall(string length) { //啦啦啦 } } public class GreatWall:Wall { public GreatWall(string length):base(length) { //啦啦啦 } }
這種方法的用處在於客戶調用不需要去知道子類,只需要知道type就行了,當然具體情況具體對待,你也可以不用這麼寫
然後這個所謂的引用變量的穩妥一點的做法還是要判斷一下這個對象存不存在,不存在就去取值,存在就直接調用。
4、將引用對象改為值對象
是的,你沒有看錯,當你千辛萬苦改成了值對象之後,有個需求第二天可能又會讓你改回來。。
動機:因為你的引用對象很小且不可變,而且不易管理。
不可變是什麼鬼?我看了《重構》這個看了半天,最後才弄明白。
還是用分類緩存來說,淘寶的緩存就是可變的,因為淘寶的緩存假如作為商家的你可以自己去去增加分類,然後刷新它,那麼所有的客戶得到的分類都變了。
那麼不可變是就是:
我在本地把百度首頁改成這樣,但是你們這些人並不知道我已經在用谷歌了╮(╯▽╰)╭
換句話說,有天,馬老板說咱淘寶分類就這麼搞了,無論怎樣就這麼多分類了,不許商家去增加分類,那麼,這個緩存就是不可變的了,某天他說不要那麼多分類了,就假貨和真貨兩個類的時候,那麼引用對象足夠小了
那麼這個引用對象也就不需要了,改成值對象就好了,比如像百度一下直接作為文本,寫死在頁面上了。
好吧,我就是這麼理解的。
正經話:引用對象就是客戶公用的,當我去改動後,其他客戶看到的也就變了,而值對象不是,當我改動後只有我自己這邊變了。(懂了嗎,我覺得自己已經講得很清楚了)
5、以對象取代數組
修改點:你有一個數組,其中的元素代表不同的東西
做法:以對象替換數組,對於數組中的每個東西,以一個字段來表示。
換句話說,有個混蛋把DateTime的年月日寫在一個int date[3];這樣的東西裡面,其中date[0]代表年,date[1]代表月,你是否想要打死他?
--未完待續