久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: 設計模式之策略模式——Strategy Pattern [打印本頁]

作者: 51黑tt    時間: 2016-3-5 23:45
標題: 設計模式之策略模式——Strategy Pattern
*
策略設計模式隸屬行為模式,行為模式關注于算法和算法間的通訊。策略是在給定輸入條件下,實現某個目標的計劃或方案。策略與算法類似,算法是定義好的過程,由多個操作組成,操作可分散實現于不同的類中,我們需要管理和維護這些類。行為模式捕捉操作在類間的劃分方式,并優化如何處理其通訊。策略是一個計劃,它也涉及從一組輸入獲得一組輸出。通常,與算法相比策略是更大范圍的可選方案,策略通常代表一組或一簇可以相互替換的方案。(通常情況下可認為其同義),策略也可以是被使用的數據。
當有多個可用的策略時,會存在一個策略選擇的問題。當你把策略看成到達目的地的道路時,策略選擇就像一個路由器了,它內部封裝路由算法(策略選擇邏輯,一般策略的選擇會有一個依據,比如根據上下文環境(自身的或外部的),或是隨機選擇一個)。
*
**
意圖:
策略模式的意圖在于,從算法的宿主(host)類中,將算法分離出來放到一個獨立的類里。對于一個問題的解決可能有若干個算法(策略)可行。如果算法保留在宿主類中,會產生一些混亂的條件語句(路由選擇)。策略模式允許客戶端(client)從一個算法族中選擇一個算法并給其一個簡單的方式去訪問它。這些被分離出來的算法會實現一個共同的操作(操作定義于接口中)。策略操作定義了策略的輸入與輸出,策略實現的工作會留給各個類,這些類以不同的方案實現同一操作,他為宿主類提供了統一的接口,因而這些類是可替換的。這符合類原理類的原理中的: 依賴性倒置和Liskov替代原理。
**
***
應用策略模式的例子。
經典的策略模式例子就是排序算法。有很多的排序算法,如冒泡,歸并(java集合排序用此算法),快速,線性排序,shell排序等。這些算法在特定情形下其中的一些會比另一些更“合適”,在時空性價比上更好些。這些算法的輸入都是一樣的(亂序或有序集合)輸出也是一樣的(已排序的集合)。但其內部實現不同,在什么條件下選擇那個算法就是一個策略選擇問題。每個算法都有相同的操作如:Collection Sort(Collection SomeArray);
關于排序算法請參考數據結構方面的書籍或資料。
***
****
模式圖示(點擊看大圖):

在給定上下文中,合適的策略會從可用的策略簇中選出。
策略的角色:
1.上下文(context):一個對策略將要工作其中的上下文(即環境)信息的維護者。(Host類)
2.策略接口(IStrategy):為所有的策略定義公共的操作接口。
3.具體策略(concreteStratety):實現策略接口中的操作,該類含有具體的算法。
****
*****
所有的設計模式中的類圖都是角色。我們不必拘泥于其名稱,其中的方法簽名也是可改變的,在我們的環境中我們需要一些指派(assignment),由我們自定義的類來承擔那些角色。
以下給出一個該模式實現的示例:
描述:有一個人“小明”或是“小王”它們將去旅游,由于資金的問題,他們會選擇不同的交通工具;
第一種Person版本中會根據自己擁有的錢來選擇不同的旅游策略:坐飛機,坐高客,或是坐火車。
使用策略模式后。將旅游的策略部分提到Person外部,僅讓Person依賴一個抽象的交通工具(IVehicle)現在
Person中的Travel方法僅調用IVehicle的TravelTo方法。至于具體交通工具的決策邏輯已經提到Person類外了。
來看我的練習代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StrategyPatternDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Console.WriteLine("<<--start 策略模式示例...."+'\n');
            //********測試*******************************************************************
            Test1();
            Test2();
            //********測試*******************************************************************
            System.Console.WriteLine();
            System.Console.WriteLine(" 策略模式示例....--end>>");
            System.Console.ReadLine();
        }
        static void Test1() {
            //不使用策略設計模式的示例
            Person p = new Person();
            p.Name = "小明";
            p.Money = 1500;
            System.Console.WriteLine("{0}有{1}元",p.Name ,p.Money );
            p.Travel("北京");
        }
        static void Test2() {
            System.Console.WriteLine();
            System.Console.WriteLine("<<--startTest2: 重構為策略模式后");
            Person_V1 p = new Person_V1();
            p.Name = "小王";
            p.Money = 900;
            IVehicle decisionVehicle;
            if (p.Money >= 2000) {
                decisionVehicle = new Airliner();
            }
            else if (p.Money >= 1000)
            {
                decisionVehicle = new Coach();
            }
            else {
                decisionVehicle = new Train();
            }
            p.RecommendedTravelBy(decisionVehicle);
            System.Console.WriteLine("{0}有{1}元",p.Name ,p.Money );
            p.Travel("上海");
            System.Console.WriteLine(" 重構為策略模式后 endTest2-->>");
        }
    }
//*****************原始類********************************************************************
    class Person{
        private string name;
        private double money;
        public Person() {
            this.name = "[SomePerson]";
            this.money = 0.0D;
        }
        public string Name {
            set { this.name = value; }
            get { return this.name; }
        }
        public double Money {
            set { this.money = value; }
            get { return this.money; }
        }
        public void Travel(string where) {
            if (money >= 2000) {
                this.TravelByairliner(where);
            }
            else if (money >= 1000)
            {//暗含邏輯小于2000
                this.TravelByCoach(where );
            }
            else {
                this.TravelByTrain(where );
            }
        }
        #region TravelBySomeVehicle
        private void TravelByairliner(string toSomewhere)
        {
            System.Console.WriteLine("坐飛機去{0} ", toSomewhere);
        }
        private void TravelByTrain(string toSomewhere)
        {
            System.Console.WriteLine("坐火車去{0}", toSomewhere);
        }
        private void TravelByCoach(string toSomewhere)
        {
            System.Console.WriteLine("坐高客去{0} ", toSomewhere);
        }
        #endregion
    }
    //*****************原始類********************************************************************
    //*****************重構后********************************************************************
    class Person_V1
    {
        private string name;
        private double money;
        public Person_V1()
        {
            this.name = "[SomePerson]";
            this.money = 0.0D;
        }
        public string Name
        {
            set { this.name = value; }
            get { return this.name; }
        }
        public double Money
        {
            set { this.money = value; }
            get { return this.money; }
        }
        //*********策略對象可由外部傳入*************************************
        private IVehicle vehicle;//某交通工具
        public void RecommendedTravelBy(IVehicle someVehicle){
            this.vehicle = someVehicle;//交通工具由外部決定
         }
        //*********策略對象可由外部傳入*************************************
        public void Travel(string where)
        {
            if (this.vehicle == null)
            {
                System.Console.WriteLine("并未指定交通工具!");
            }
            else
            {
                this.vehicle.TravelTo(where);
            }
        }
      
    }
    #region IStrategy_Interface   策略接口
    public interface IVehicle {
        //策略接口,定義了一個操作TravelTo
        void TravelTo(string where);
    }
    #endregion
   
    #region ConcreteStrategy_Classes 策略實現者類
   
    public class Airliner : IVehicle {
        #region IVehicle 成員
        public void TravelTo(string where)
        {
            //對操作TravelTo的實現
            System.Console.WriteLine("坐飛機去{0} ", where);
        }
        #endregion
    }
    public class Train : IVehicle {

        #region IVehicle 成員
        public void TravelTo(string where)
        {
            System.Console.WriteLine("坐火車去{0}", where);
        }
        #endregion
    }

    public class Coach : IVehicle {

        #region IVehicle 成員
        public void TravelTo(string where)
        {
            System.Console.WriteLine("坐高客去{0} ", where);
        }
        #endregion
    }
    #endregion
    //******************重構后*******************************************************************
}
上面策略模式的應用為我們帶來的好處:Person類不再親自決定到底使用那種交通工具了,策略選擇邏輯已被分離出去了,任何實現策略接口的具體類現在都可被傳入到Person類中。這樣體現了可擴展性。Person類只執行策略就可以了。
就向這樣的情形。一個企業中,高層指定戰略計劃,中層負責執行戰略,中層不需要選擇戰略計劃塔們只知道執行計劃,決策邏輯交給高層去吧!
*****
******
策略設計模式的UML圖示很簡單,它們只是角色示意而已,到底誰來實現這個角色,模式并沒有明說,我們其實也可以將決策邏輯仍放在策略執行者之內(這里就是指Person類,),它甚至可有一個策略列表,用來存放可用的策略,如果你在提供增加,刪除,或替換策略的公共接口方法,那就更帥了!
策略模式的圖示,與狀態模式的結構是一樣的,它們都符合類原理:依賴抽象。
但與策略模式不同的是。狀態模式中存在對象的狀態轉移,它是對狀態機的建模。
在本例中,Person有一個屬性Money,它也可以表示Person當下的狀態,但是執行某個操作后我們后續并沒有改變它的狀態(比如說,讓他的錢財減少)。因為策略的選擇總是有些依據的,這里就依賴了Person內部的狀態,但是我們還可以依賴外部的狀態或環境(就是角色中的那個Context上下文)。狀態模式中,操作的具體行為總是依賴系統內部的具體狀態對象,操作完備后必要時還需要置換當前的狀態對象。但無論如何它們都能改善我們的設計,我們需認真選擇什么環境下使用那個模式。
另外提一點,《重構》一書提到,如果代碼中出現了過多的選擇語句,IF..if else..if...else。Switch(){case:case:case:....}。在面向對象語境下都是代碼壞味道的體現,這些結構典型的屬于面向過程的編程方式,在面向對象中都能用多態去除。我們上面的示例中仍然有這樣的結構,有興趣的朋友可以試試想法去掉它們。






歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 色婷婷av一区二区三区软件 | 亚洲一区精品视频 | 网站国产 | 亚洲成年人免费网站 | 日韩精品一区二区三区中文字幕 | 99热精品6 | 在线观看一区 | 国产丝袜一区二区三区免费视频 | 久久久国产一区二区三区 | jdav视频在线观看免费 | 国产一级毛片视频 | 国产精品美女一区二区三区 | 亚洲一区二区视频 | 中文字幕日韩欧美一区二区三区 | 天天干.com | 一级毛片免费完整视频 | 日韩成人在线播放 | 亚洲精品黄 | 中文字幕精品一区二区三区精品 | 国产91在线 | 亚洲 | 久久国产精品99久久久久久丝袜 | 超碰在线人人 | 亚洲欧美一区二区三区国产精品 | 一区二区三区精品在线视频 | 午夜国产精品视频 | 久久在线精品 | 91高清视频在线 | 国产成人免费 | 黄视频国产| 免费观看成人鲁鲁鲁鲁鲁视频 | 久久99深爱久久99精品 | 亚洲精品在线观看视频 | 日韩精品亚洲专区在线观看 | 久久激情五月丁香伊人 | 久久久入口 | 欧美美女爱爱视频 | 欧美极品视频 | www.久久久.com| 国产区在线 | 国产精品视频一区二区三区 | 成人在线播放网站 |