小菜編程成長記(八 反射——程序員的快樂!)
[2] 小菜編程成長記(八 反射——程序員的快樂!)
[3] 小菜編程成長記(八 反射——程序員的快樂!)
系列文章導航:
小菜編程成長記(九 會修電腦不會修收音機?——聊設計模式原則)
小菜編程成長記(十一 無熟人難辦事?——聊設計模式迪米特法則)
小菜編程成長記(十三 設計模式不能戲說!設計模式怎就不能戲說?)
(續上篇)
“到底如何去改良策略模式呢?”小菜懇切地問道。
“你仔細觀察過沒有,你的代碼,不管是用工廠模式寫的,還是用策略模式寫的,那個分支的switch依然去不掉。原因在哪里?”大鳥反問道。
“因為程序里有下拉選擇,用戶是有選擇的,那么程序就必須要根據用戶的選擇來決定實例化哪一個子類對象。無論是在客戶端窗體類編程還是到工廠類里編程,這個switch總是少不掉的。問題主要出在這里。”小菜十分肯定的說。
“是呀,”大鳥道,“所以我們要考慮的就是可不可以不在程序里寫明‘如果是打折就去實例化CashRebate類,如果是返利就去實例化 CashReturn類’這樣的語句,而是在當用戶做了下拉選擇后,再根據用戶的選擇去某個地方找應該要實例化的類是哪一個。這樣,我們的switch就 可以對它說再見了。”
“聽不太懂哦,什么叫‘去某個地方找應該要實例化的類是哪一個’?’小菜糊涂地說。
“,我要說的就是一種編程方式:依賴注入(Dependency Injection),從字面上不太好理解,我們也不去管它。關鍵在于如何去用這種方法來解決我們的switch問題。本來依賴注入是需要專門的IoC容 器提供,比如spring.net,顯然當前這個程序不需要這么麻煩,你只需要再了解一個簡單的.net技術‘反射’就可以了。”
“大鳥,你一下子說出又是‘依賴注入’又是‘反射’這些莫名其妙的名詞,我有點暈哦!”小菜有些犯困,“我就想知道,如何向switch說bye-bye!至于那些什么概念我不想了解。”
“心急討不了好媳婦!你急什么?”大鳥嘲笑道,“反射技術看起來很玄乎,其實實際用起來不算難。”
“請看下面的兩個樣例:
Code
其中關鍵是
Assembly.Load("程序集名稱").CreateInstance("名稱空間.類名稱")
那也就是說,我們可以在實例化的時候,再給計算機一個類的名稱字符串,來讓計算機知道應該實例化哪一個類。”大鳥講解道。
“你的意思是,我之前寫的‘cc.setBehavior(new CashNormal());’可以改寫為‘cc.setBehavior((CashSuper)Assembly.Load("商場管理軟 件").CreateInstance("商場管理軟件.CashNormal")’,不過,這只不過是換了種寫法而已,又有什么神奇之處呢?”小菜依然 迷茫。
“分析一下,原來new CashNormal()是什么?是否是寫死在程序里的代碼,你可以靈活更換嗎?”大鳥問。
“不可以,那還換什么,寫什么就是什么了唄。”
“那你說,在反射中的CreateInstance("商場管理軟件.CashNormal"),可以靈活更換‘CashNormal’嗎?”大鳥接著問。
“還不是一樣,寫死在代碼…………等等,哦!!!我明白了。”小菜一下子頓悟過來,,興奮起來。“因為這里是字符串,可以用變量來處理,也就可以根據需要更換。哦,My God!太妙了!”
“哈哈,博客園中的有篇博文《四大發明之活字印刷——面向對象思想的勝利》中曾經寫過,‘體會到面向對象帶來的好處,那種感覺應該就如同是一中國酒鬼第一次喝到了茅臺,西洋酒鬼第一次喝到了XO一樣,怎個爽字可形容呀。’,你有沒有這種感覺了?”
“嗯,我一下子知道這里的差別主要在原來的實例化是寫死在程序里的,而現在用了反射就可以利用字符串來實例化對象,而變量是可以更換的。”小菜說道。