慢慢的做記錄,做最強大的自己 看了大話設計模式之後感觸很深,發現自己還有很多學習的東西,設計軟體並不是一兩句代碼把功能寫完了就行,需要思考的內容有很多 代碼來源參考大話設計模式這本書,這裡在博客里記錄一下,不可能每次都去翻書,但是在博客裡面是非常好找的。 面向對象的編程,要儘量避免重覆創建出類,做數 ...
慢慢的做記錄,做最強大的自己
看了大話設計模式之後感觸很深,發現自己還有很多學習的東西,設計軟體並不是一兩句代碼把功能寫完了就行,需要思考的內容有很多
代碼來源參考大話設計模式這本書,這裡在博客里記錄一下,不可能每次都去翻書,但是在博客裡面是非常好找的。
面向對象的編程,要儘量避免重覆創建出類,做數據處理的時候最容易出現這個問題,比如做一個商城系統,商城裡面針對同一件商品可能有不同的折扣,這是存在的,比如我的用戶對象不同。
那麼問題來了,我總不可能每次都針對商品去判斷用戶角色是什麼然後給出不同的折扣,對同一個用戶來說,不同的商品還有不同的折扣,寫if語句來判斷這時候就顯得耗時耗力了,而且代碼也並不好維護;
同樣的,用簡單工廠模式會存在一個問題,當我要新增一個折扣時,那麼我必然要去修改工廠里的東西,這種情況下,用工廠模式肯定是不行的,這時候我們就需要用到策略模式。
像打折這一類的情況分幾種,我有直接的折扣,也有滿多少返現多少,那麼我怎麼統一這種方法,然後讓一個策略類定義這些折扣類,下麵看下詳細的代碼:
首先,創建一個折扣的類:
abstract class CashSuper { public abstract double acceptCash(double money); } //正常收費子類 class CashNormal : CashSuper { public override double acceptCash(double money) { return money; } } //打折收費子類 class CashRebate : CashSuper { private double moneyRebate = 1d; //打折收費率,初始化時,必須要輸入折扣率,如八折就是0.8 public CashRebate(string moneyRebate) { this.moneyRebate = double.Parse(moneyRebate); } public override double acceptCash(double money) { return money * moneyRebate; } } //返利收費子類 class CashReturn : CashSuper { private double moneyCondition = 0.0d; //返利條件 private double moneyReturn = 0.0d; //返利值 public CashReturn(string moneyCodition, string moneyReturn) { this.moneyCondition = double.Parse(moneyCodition); this.moneyReturn = double.Parse(moneyReturn); } public override double acceptCash(double money) { double result = money; if (money > moneyCondition) { result = money - Math.Floor(money / moneyCondition) * moneyReturn; } return result; } }
然後定義一個策略類,在實際的使用過程中,實例化不同的策略,那麼我就可以獲取不同的結果,下麵看一下這個策略模式的實現
class CashContext { private CashSuper cs; public CashContext(CashSuper csuper) { this.cs = csuper; } public double GetResult(double money) { return cs.acceptCash(money); } }
在交互端的代碼裡面我們就可以通過實例化不同的策略來實現我們的折扣方法了,這樣我們就避免了在簡單工廠類裡面反覆添加條件及相應的返回對象
具體的看客戶端裡面的策略實例化
private void button1_Click(object sender, EventArgs e) { //CashSuper csuper = CashFactory.createCashAccept(comboBox1.SelectedItem.ToString()); CashContext cs = null; switch (comboBox1.SelectedItem.ToString()) { case "正常收費": cs = new CashContext(new CashNormal()); break; case "滿300返100": cs = new CashContext(new CashReturn("300","100")); break; case "打八折": cs = new CashContext(new CashRebate("0.8")); break; } double TotalPrices = 0d; TotalPrices = cs.GetResult(Convert.ToDouble(textBox1.Text) * Convert.ToDouble(textBox2.Text)); Total = Total + TotalPrices; listBox1.Items.Add("單價:" + textBox1.Text + "數量:" + textBox2.Text + " " + comboBox1.SelectedItem + "合計:" + TotalPrices.ToString()); label4.Text = Total.ToString(); }
這裡,我們可以看到三個實例化的策略
cs = new CashContext(new CashNormal());
cs = new CashContext(new CashReturn("300","100"));
cs = new CashContext(new CashRebate("0.8"));
如果不想把這個判斷的邏輯放到交互端來處理,那麼同樣的道理,我們可以把實例化的過程轉移到策略類中,然後再把參數給傳遞進去,就可以實現這個過程了。
這裡也解釋一下策略模式:策略模式相當於你定義了一系列的計算的方法或者是處理方法,從概念上,可能這類方法處理的東西很相似,但是實現的過程不同,
他可以以相同的方式來調用所有的演算法,減少了各種演算法類與使用演算法類之間的耦合,哪怕我修改了其中的一個處理方法,也不會影響到其他的方法,對結果也不會
造成太大的影響,對使用者來說,我只需要得到結果就可以了,而跟整個過程就無關了。
下麵看一下結果吧
可能編程的代碼規範不是很規範,匆忙之間就隨便寫了一下,但是實際做項目的時候還是得註意的,下次繼續記錄其他的設計模式,對代碼優化能起到很大的作用,
特別是反射,依賴註入這些,後續都會一一記錄 下來