成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

策略(Strategy)模式

 
面向?qū)ο缶幊蹋⒉皇穷愒蕉嘣胶?,類的劃分是為了封裝,但分類的基礎(chǔ)是抽象,具有相同屬性和功能的對象的抽象集合才是類
我們在Martin編寫的《代碼整潔之道》中對類的看法,類應(yīng)該短?。ㄩL度不應(yīng)該容納一個if嵌套語句,20行封頂),而且只做一件事,做好這件事。強調(diào)的是簡潔和優(yōu)雅,但是不沒說類越多越好。
這里我們可以明白我們應(yīng)該用什么態(tài)度來看待和創(chuàng)建類,對我們的工程很重要。
策略模式的定義:
策略(Strategy)模式
 
策略模式UML:
策略(Strategy)模式
 
 
主要的東西還是Context的配置,傳入具體的策略,然后返回出對應(yīng)策略的的結(jié)果。
下面是收費策略的一個事例

//收費策略Context class CashContext { //聲明一個現(xiàn)金收費父類對象 private CashSuper cs; //設(shè)置策略行為,參數(shù)為具體的現(xiàn)金收費子類(正常,打折或返利) public CashContext(CashSuper csuper) { this.cs = csuper; } //得到現(xiàn)金促銷計算結(jié)果(利用了多態(tài)機制,不同的策略行為導(dǎo)致不同的結(jié)果) public double GetResult(double money) { return cs.acceptCash(money); } }
簡單工廠與策略模式的結(jié)合是比較常見的。
 
簡單工廠與策略模式結(jié)合事例(把客戶端的switch給封裝了,封裝了變化的體現(xiàn))
 
策略(Strategy)模式策略(Strategy)模式View Code     //現(xiàn)金收取工廠 class CashContext {     CashSuper cs = null ;       //根據(jù)條件返回相應(yīng)的對象     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 + " 數(shù)量:" + txtNum.Text + "" + cbxType.SelectedItem + " 合計:" + totalPrices.ToString());             lblResult.Text = total.ToString();         }


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

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

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

策略(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();             //根據(jù)用戶的選項,查詢用戶選擇項的相關(guān)行             DataRow dr = ((DataRow[])ds.Tables[0].Select("name='" + cbxType.SelectedItem.ToString()+"'"))[0];             //聲明一個參數(shù)的對象數(shù)組             object[] args =null;             //若有參數(shù),則將其分割成字符串?dāng)?shù)組,用于實例化時所用的參數(shù)             if (dr["para"].ToString() != "")                 args = dr["para"].ToString().Split(',');             //通過反射實例化出相應(yīng)的算法對象             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 + " 數(shù)量:" + txtNum.Text + ""+cbxType.SelectedItem+ " 合計:" + totalPrices.ToString());             lblResult.Text = total.ToString();         }

而我們的配置類就應(yīng)該是實現(xiàn)反射的類如下:
策略(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);     } }
到此為止我們使用簡單工廠策略模式+反射實現(xiàn)了一種數(shù)據(jù)驅(qū)動的方式實現(xiàn)了代碼0修改。
數(shù)據(jù)驅(qū)動是我們常用的一種設(shè)計方案,這是一種偉大的進(jìn)步,從數(shù)據(jù)驅(qū)動直到今天的腳本游戲引擎比如說unity3d............扯遠(yuǎn)了....下一篇來吧....................................
 
如果需要可以下載源碼:D
http://www.cnblogs.com/Wonder1989/archive/2013/03/27/2985275.html
 
本博客不在跟新  請移步http://www.cnblogs.com/Wonder1989
 

分享名稱:策略(Strategy)模式
標(biāo)題來源:http://jinyejixie.com/article8/pgigop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、定制網(wǎng)站、網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計公司、Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
永德县| 原阳县| 平凉市| 仪征市| 徐闻县| 珠海市| 娄底市| 仪征市| 定兴县| 营口市| 双流县| 上高县| 宾川县| 清流县| 南川市| 繁峙县| 纳雍县| 山东省| 永善县| 瓦房店市| 涞源县| 土默特左旗| 交城县| 京山县| 新平| 历史| 隆林| 科技| 尼勒克县| 克拉玛依市| 吴江市| 澳门| 黎城县| 五大连池市| 杨浦区| 呼和浩特市| 徐水县| 雷山县| 尉氏县| 稷山县| 营山县|