熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

老生常談:策略模式

2013-11-13 10:21:49  來源: .NET編程 

  本來園子裡面已經有很多特別好的關於設計模式學習的文章但一般都是概念性的或者都是些簡單實例沒有用過設計模式的朋友看過之後雖然明白怎麼回事了但是對於自己實際項目中何時用設計模式就不太清楚了本人借jillzhang開發的控件中的部分代碼與大家討論下模式在具體項目中的應用好的代碼應該與大家分享

  名詞解釋:

  策略:
         :戰略(學)

  :策略 計謀 作戰方針; 智謀 手腕

  從策略一詞來看策略模式是種傾向於行為的模式有點類似找仗時的做戰方案一般司令員在做戰前都會根據實際情況做出幾套不同的方案如果當時情況有變就會根據相應的條件來判定用哪一套方案來替換原定方案但無論如何替換替換多少次仗還是要打的

  在他的文章中給GRIDVIEW添加上數據導出成EXCELWORDPDF文件的功能這三類導出雖然具體操作略有不同但是大部分都相同

  具體策略模式的類圖: 

  策略模式定義(GOF):

  策略模式:主要是定義一系列的算法把這些算法一個個封裝成擁有共同接口的類它們之間可以互換使客戶端調用它們的時候能夠互不影響地變化

  具體代碼如下

  第一數據導出的接口類:IExporter

  抽象策略(Strategy)角色這是一個抽象角色通常由一個接口或抽象類實現此角色給出所有的具體策略類所需的接口

  

  


Code
/**//// <summary>
    /// 將GridView導出到其他文件的接口
    /// </summary>
    public interface IExporter
    {
        /**//// <summary>
        /// 輸出編碼
        /// </summary>
        Encoding ResponseEncoding { get;}

        /**//// <summary>
        /// 導出文件的名稱
        /// </summary>
        string ExportFileName { get;}

        /**//// <summary>
        /// 將GirdView導出為其他格式的文件
        /// </summary>
        /// <param name=grid>要導出的GridView對象</param>
        /// <param name=unExportedColumnNames>不導出的列名稱集合</param>
        void Export(GridViewEx grid);
        

    }

  下面為實現了此接口的抽象類


Code
public abstract class Exporter:IExporter
    {
        private fields#region private fields  
        Encoding _responseEncoding;
        string _exportFileName;
        #endregion

        my constructors#region my constructors
        public Exporter(Encoding encoding string outName)
        {
            this_responseEncoding = encoding;
            this_exportFileName = outName;
        }  
        #endregion

        public property#region public property
        /**//// <summary>
        /// 輸出編碼
        /// </summary>
        public Encoding ResponseEncoding
        {
            get
            {
                return _responseEncoding;
            }
        }
        /**//// <summary>
        /// 導出文件的名稱
        /// </summary>
        public string  ExportFileName
        {
            get
            {
                return _exportFileName;
            }
        }
        #endregion

       

         public methods#region public methods
        /**//// <summary>
        /// 將GirdView導出為其他格式的文件
        /// </summary>
        /// <param name=grid>要導出的GridView對象</param>
        /// <param name=unExportedColumnNames>不導出的列名稱集合</param>
        public abstract void Export(GridViewEx grid);     
        #endregion

        private methods#region private methods
        protected string ReplaceHref(string html)
        {
            string content = RegexReplace(html (<a[^>]+>)|(</a>) );
            return content;
        }
        protected virtual void Export(GridViewEx grid string extension string contentType)
        {
            //具體代碼略
        }
        #endregion
    }

  第二context

  環境(Context)角色持有一個Strategy類的引用


Code
DropDownList drop = dropList;
            if (drop != null)
            {
                if (dropSelectedIndex > )
                {
                    switch (dropSelectedValue)
                    {
                        case Excel:
                            {
                                IExporter exporter = new ExcelExporter(EncodingGetEncoding(gb) this_exportFileName);
                                ExporterHelperExport(Owner exporter);
                                break;
                            }
                        case Word:
                            {
                                IExporter exporter = new WordExporter(EncodingGetEncoding(gb) this_exportFileName);
                                ExporterHelperExport(Owner exporter);
                                break;
                            }
                        case Pdf:
                            {
                                IExporter exporter = new PdfExporter(EncodingGetEncoding(gb) this_exportFileName);
                                ExporterHelperExport(Owner exporter);
                                break;
                            }
                    }
                }
            }

  [nextpate]

  第三具體實現類

  具體策略(ConcreteStrategy)角色包裝了相關的算法或行為

  下面是三個具體操作類


Code
/**//// <summary>
    /// Excel導出
    /// </summary>
    public class ExcelExporter:Exporter
    {
        private fields#region private fields
        static readonly string extension = xls;
        static readonly string contentType = application/vndxls;       
        #endregion

        my constructors#region my constructors   
        public ExcelExporter(Encoding encodingstring outName):base(encodingoutName)
        {
          
        }
        #endregion

     

        public methods#region public methods
        /**//// <summary>
        /// 將GirdView導出為其他格式的文件
        /// </summary>
        /// <param name=grid>要導出的GridView對象</param>
        /// <param name=unExportedColumnNames>不導出的列名稱集合</param>
        public override void Export(GridViewEx grid)
        {
            Export(grid extension contentType);
        }
        #endregion

  PdfExporter:


Code
public class PdfExporter : Exporter
    {
        static readonly string extension = pdf;
        static readonly string contentType = application/pdf;
        public PdfExporter(Encoding encoding string outName)
            : base(encoding outName)
        {

        }
        public override void Export(GridViewEx grid)
        {
            //具體代碼略
        }
    }

  WordExporter:


Code
/**//// <summary>
    /// Word導出
    /// </summary>
    public  class WordExporter:Exporter
    {
        private fields#region private fields
        static readonly string extension = doc;
        static readonly string contentType = application/msword;       
        #endregion

        my constructors#region my constructors   
        public WordExporter(Encoding encoding string outName)
            : base(encoding outName)
        {
          
        }
        #endregion

       
        public methods#region public methods
        /**//// <summary>
        /// 將GirdView導出為其他格式的文件
        /// </summary>
        /// <param name=grid>要導出的GridView對象</param>
        /// <param name=unExportedColumnNames>不導出的列名稱集合</param>
        public override void Export(GridViewEx grid)
        {
            Export(grid extension contentType);
        }
        #endregion

       
    }

      

  策略模式優點

          算法的使用和算法本身解耦即把變化的具體算法封裝了起來策略模式是除了繼承之外的一種彈性替代方案如果你使用繼承定義了一個類下面有部分的派生類此時你會讓基類所困住要想修改它特別不容易而策略模式則可能通過組合不同的對象來改變行為 

  策略模式缺點

   雖說客戶代碼無須關心各個策略是如何實現的但是它們還是要知道有多少種策略實現具體功能情況這樣才可以根據需要使用哪個策略

   使用策略模式後出現很多小類

  總結

  設計模式的有效應用能夠給我們的開發帶來效率同時也是把雙刃劍濫用設計模式往往會費力不計好本人在實際開發中對於模式的應用還不是特別多如果有什麼地方說錯了還望大家諒解  


From:http://tw.wingwit.com/Article/program/net/201311/13392.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.