亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

策略(Strategy)模式

發布時間:2020-07-08 23:32:09 來源:網絡 閱讀:418 作者:Wonder_1989 欄目:編程語言
 
面向對象編程,并不是類越多越好,類的劃分是為了封裝,但分類的基礎是抽象,具有相同屬性和功能的對象的抽象集合才是類
我們在Martin編寫的《代碼整潔之道》中對類的看法,類應該短小(長度不應該容納一個if嵌套語句,20行封頂),而且只做一件事,做好這件事。強調的是簡潔和優雅,但是不沒說類越多越好。
這里我們可以明白我們應該用什么態度來看待和創建類,對我們的工程很重要。
策略模式的定義:
策略(Strategy)模式
 
策略模式UML:
策略(Strategy)模式
 
 
主要的東西還是Context的配置,傳入具體的策略,然后返回出對應策略的的結果。
下面是收費策略的一個事例

//收費策略Context class CashContext { //聲明一個現金收費父類對象 private CashSuper cs; //設置策略行為,參數為具體的現金收費子類(正常,打折或返利) public CashContext(CashSuper csuper) { this.cs = csuper; } //得到現金促銷計算結果(利用了多態機制,不同的策略行為導致不同的結果) public double GetResult(double money) { return cs.acceptCash(money); } }
簡單工廠與策略模式的結合是比較常見的。
 
簡單工廠與策略模式結合事例(把客戶端的switch給封裝了,封裝了變化的體現)
 
策略(Strategy)模式策略(Strategy)模式View Code     //現金收取工廠 class CashContext {     CashSuper cs = null ;       //根據條件返回相應的對象     public CashContext(string type)     {         switch (type)         {             case "正常收費" :                 CashNormal cs0 = new CashNormal();                 cs = cs0;                 break;             case "滿300返100" :                 CashReturn cr1 = new CashReturn( "300", "100" );                 cs = cr1;                 break;             case "打8折" :                 CashRebate cr2 = new CashRebate( "0.8");                 cs = cr2;                 break;         }     }       public double GetResult(double money)     {         return cs.acceptCash(money);     } }


但是單是試用策略模式客戶端如下:

策略(Strategy)模式策略(Strategy)模式View Code  private void btnOk_Click(object sender, EventArgs e)         {             CashContext cc = null ;             switch (cbxType.SelectedItem.ToString())             {                 case "正常收費" :                     cc = new CashContext (new CashNormal());                     break;                 case "滿300返100" :                     cc = new CashContext (new CashReturn("300" , "100"));                     break;                 case "打8折" :                     cc = new CashContext (new CashRebate("0.8" ));                     break;             }               double totalPrices = 0d;             totalPrices = cc.GetResult( Convert.ToDouble(txtPrice.Text) * Convert .ToDouble(txtNum.Text));             total = total + totalPrices;             lbxList.Items.Add( "單價:" + txtPrice.Text + " 數量:" + txtNum.Text + " " + cbxType.SelectedItem + " 合計:" + totalPrices.ToString());             lblResult.Text = total.ToString();         }


如果與簡單工廠結合客戶端就有交大改善:
策略(Strategy)模式策略(Strategy)模式View Codeprivate void btnOk_Click(object sender, EventArgs e)         {             //利用簡單工廠模式根據下拉選擇框,生成相應的對象             CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());             double totalPrices = 0d;             //通過多態,可以得到收取費用的結果             totalPrices = csuper.GetResult( Convert.ToDouble(txtPrice.Text) * Convert .ToDouble(txtNum.Text));             total = total + totalPrices;             lbxList.Items.Add( "單價:" + txtPrice.Text + " 數量:" + txtNum.Text + " "                 + cbxType.SelectedItem + " 合計:" + totalPrices.ToString());             lblResult.Text = total.ToString();         }

對比一下可以知道后則只暴露了一個配置類Content而前者必須要客戶端知道除了配置類其他的類,這樣前者耦合性更低。
后則也把判斷從客戶端的判斷條件給移除了,這樣客戶端判斷壓力減小了。
在定義上該模式是封裝算法的,但是我幾個人建議學習設計模式千萬不要因為模式而模式,要因需求和設計而模式。因此
只要是不同時間要應用不同的業務那么這時候就該考慮策略模式了 。
總結:
策略模式與簡單工廠的區別:
主要就是用Content上下文配置,客戶端通過條件判斷傳遞一個事例,然后實化對應對像,
加上一個GetResult方法算出結果,客戶端調用該方法返回結果得到值。這里對算法進行了封裝
--------------------------------------------------------------------------------------------------------------
而簡單工廠就是客戶端只需要傳遞一個判斷標識,然后工廠根據標識做出判斷應該返回什么事例,
客戶端拿到返回事例對象,通過調用該對象得到返回結果。這里對判斷后置了減少了客戶端判斷壓力
策略模式與簡單工廠策略模式區別:
就是對前者優點的結合。
既封裝了算法也減少了客戶端判斷壓力
---------------------------------------------------------------------------------------------------------------
到此為止如果需求變動(增加一種算法)那么我們還是需要修改switch 條件
增加一個具體的算法類。

那么該如何讓其不改動代碼呢?對就是反射
我們以一種數據驅動的形式來處理這個問題,下拉框內存我們通過讀取配置文件獲取
客戶端只需要傳入類名和需要的參數即可如下:

策略(Strategy)模式策略(Strategy)模式View CodeDataSet ds;//用于存放配置文件信息         double total = 0.0d;//用于總計          private void Form1_Load(object sender, EventArgs e)         {             //讀配置文件             ds = new DataSet();             ds.ReadXml(Application.StartupPath + "\\CashAcceptType.xml");             //將讀取到的記錄綁定到下拉列表框中             foreach (DataRowView dr in ds.Tables[0].DefaultView)             {                 cbxType.Items.Add(dr["name"].ToString());             }             cbxType.SelectedIndex = 0;         }          private void btnOk_Click(object sender, EventArgs e)         {             CashContext cc = new CashContext();             //根據用戶的選項,查詢用戶選擇項的相關行             DataRow dr = ((DataRow[])ds.Tables[0].Select("name='" + cbxType.SelectedItem.ToString()+"'"))[0];             //聲明一個參數的對象數組             object[] args =null;             //若有參數,則將其分割成字符串數組,用于實例化時所用的參數             if (dr["para"].ToString() != "")                 args = dr["para"].ToString().Split(',');             //通過反射實例化出相應的算法對象             cc.setBehavior(dr["class"].ToString(), args);                         double totalPrices = 0d;             totalPrices = cc.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));             total = total + totalPrices;             lbxList.Items.Add("單價:" + txtPrice.Text + " 數量:" + txtNum.Text + " "+cbxType.SelectedItem+ " 合計:" + totalPrices.ToString());             lblResult.Text = total.ToString();         } 

而我們的配置類就應該是實現反射的類如下:
策略(Strategy)模式策略(Strategy)模式View Codeclass CashContext {     private CashSuper cs;      public void setBehavior(string className, object[] args)     {         this.cs = (CashSuper)Assembly.Load("商場管理軟件").CreateInstance("商場管理軟件." + className, false, BindingFlags.Default, null, args, null, null);     }      public double GetResult(double money)     {         return cs.acceptCash(money);     } }
到此為止我們使用簡單工廠策略模式+反射實現了一種數據驅動的方式實現了代碼0修改。
數據驅動是我們常用的一種設計方案,這是一種偉大的進步,從數據驅動直到今天的腳本游戲引擎比如說unity3d............扯遠了....下一篇來吧....................................
 
如果需要可以下載源碼:D
http://www.cnblogs.com/Wonder1989/archive/2013/03/27/2985275.html
 
本博客不在跟新  請移步http://www.cnblogs.com/Wonder1989
 
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宁武县| 电白县| 泉州市| 达日县| 绥滨县| 沙河市| 秦安县| 浮山县| 河间市| 龙州县| 龙门县| 高碑店市| 平乐县| 乌兰县| 米林县| 壶关县| 广州市| 文化| 黄浦区| 娱乐| 博野县| 双鸭山市| 西乌珠穆沁旗| 墨江| 新郑市| 天峨县| 肇庆市| 苏州市| 乌兰察布市| 阿荣旗| 博客| 澄迈县| 陆河县| 信宜市| 双鸭山市| 岳阳市| 资溪县| 合水县| 德化县| 庆云县| 都匀市|