自動(dòng)駕駛談?wù)劇籂顟B(tài)模式』

目錄:設(shè)計(jì)模式之小試牛刀
源碼路徑:Github-Design Pattern


定義(State Pattern):

當(dāng)一個(gè)對(duì)象內(nèi)在狀態(tài)改變時(shí)允許其改變行為,這個(gè)對(duì)象看起來(lái)像改變了其類股囊。

類圖:

狀態(tài)模式通用類圖

啟示:

最近幾年寓辱,自動(dòng)駕駛被炒的是熱火朝天放航,國(guó)外的知名google语淘、uber妇汗、tesla惠拭,國(guó)內(nèi)的百度扩劝、樂視也都投入到了自動(dòng)駕駛的浪潮中去。像google和tesla的自動(dòng)駕駛技術(shù)已經(jīng)相對(duì)成熟职辅,可以上路了。比較火的純電動(dòng)支持自動(dòng)駕駛的特斯拉可謂是紅極一時(shí)聂示,官網(wǎng)號(hào)稱所有車型均搭載全自動(dòng)駕駛硬件域携。自動(dòng)駕駛作為一種發(fā)展趨勢(shì),相信在不久的將來(lái)鱼喉,我們每個(gè)人都能享受到這科技的紅利秀鞭。

說(shuō)到科技,我們就來(lái)簡(jiǎn)單探討下自動(dòng)駕駛涉及到的技術(shù)扛禽。首先锋边,這一切都需要必不可少的硬件支持,比如傳感器编曼、攝像頭豆巨、雷達(dá)。有了硬件就可以進(jìn)行數(shù)據(jù)采集掐场,收集駕駛過程中的各種信息往扔,通過算法進(jìn)行數(shù)據(jù)分析,來(lái)控制當(dāng)前的駕駛行為熊户。
換句話說(shuō)萍膛,自動(dòng)駕駛是結(jié)合外部因素和內(nèi)部因素通過算法分析來(lái)控制驅(qū)動(dòng)的。外部因素?zé)o外乎道路狀況嚷堡、交通標(biāo)志等蝗罗。內(nèi)部因素比如電池容量、車況等等蝌戒。

那這跟我們這節(jié)講的狀態(tài)模式有什么區(qū)別呢串塑?
在我理解,自動(dòng)駕駛也是狀態(tài)和行為相結(jié)合的瓶颠。
比如攝像頭檢測(cè)到路邊的限速標(biāo)記拟赊,自動(dòng)控制車速,比如攝像頭檢測(cè)到前方十字路口交通信號(hào)燈為紅燈粹淋,則停車等待吸祟。
其中限速標(biāo)記和交通燈都是一個(gè)狀態(tài)的體現(xiàn)瑟慈,控制車速和停車等待則是狀態(tài)驅(qū)動(dòng)的結(jié)果。但是呢屋匕,這些狀態(tài)行為并不符合我們狀態(tài)模式的定義(當(dāng)一個(gè)對(duì)象內(nèi)在狀態(tài)改變時(shí)允許其改變行為)葛碧。很顯然限速標(biāo)記和交通燈是外部狀態(tài)。

別失望过吻,我們來(lái)找找特斯拉的內(nèi)部狀態(tài)进泼。作為一輛車它的狀態(tài)其實(shí)很簡(jiǎn)單,也就是運(yùn)行纤虽、加速乳绕、減速、停車狀態(tài)逼纸。在停車狀態(tài)洋措,我們可以控制它啟動(dòng)運(yùn)行,切換至運(yùn)行狀態(tài)杰刽;在運(yùn)行狀態(tài)菠发,自動(dòng)駕駛根據(jù)行駛條件控制加速減速,切換至加速減速狀態(tài)贺嫂;到達(dá)目的地后滓鸠,泊車切換到停車狀態(tài)。

代碼:

這個(gè)應(yīng)用場(chǎng)景其實(shí)很簡(jiǎn)單第喳,按照我們傳統(tǒng)的寫法糜俗,我們肯定幾個(gè)if..else或用switch..case就搞定了。的確墩弯,但是呢吩跋,傳統(tǒng)的寫法就擴(kuò)展性和代碼結(jié)構(gòu)上就十分差強(qiáng)人意。廢話不多說(shuō)渔工,下面我們就以特斯拉自動(dòng)駕駛為例锌钮,分析下狀態(tài)模式的應(yīng)用。

首先我們定義一個(gè)狀態(tài)接口:

    /// <summary>
    /// 狀態(tài)接口類
    /// </summary>
    public interface ICarState
    {
        /// <summary>
        /// 啟動(dòng)
        /// </summary>
        void Drive(Car car);

        /// <summary>
        /// 停車
        /// </summary>
        void Stop(Car car);

        /// <summary>
        /// 加速
        /// </summary>
        /// <param name="car"></param>
        void SpeedUp(Car car);

        /// <summary>
        /// 減速
        /// </summary>
        /// <param name="car"></param>
        void SpeedDown(Car car);
    }

然后我們依次實(shí)現(xiàn)這四種狀態(tài)引矩。
運(yùn)行狀態(tài)下可以切換到其他三種狀態(tài)梁丘。

/// <summary>
/// 運(yùn)行狀態(tài)
/// </summary>
public class RuningState : ICarState
{
    public void Drive(Car car)
    {
        Console.WriteLine("車輛正在自動(dòng)駕駛!");
    }

    public void Stop(Car car)
    {
        Console.WriteLine("車輛已停止旺韭!");
        car.CurrentCarState = Car.StopState;
    }

    public void SpeedUp(Car car)
    {
        Console.WriteLine("路況良好氛谜,開始加速行駛!");
        car.CurrentCarState = Car.SpeedUpState;
    }

    public void SpeedDown(Car car)
    {
        Console.WriteLine("路況一般区端,開始加速行駛值漫!");
        car.CurrentCarState = Car.SpeedDownState;
    }
}

停車狀態(tài)下,只能切換到啟動(dòng)狀態(tài)织盼,不可加速減速杨何。

/// <summary>
/// 停車狀態(tài)
/// </summary>
public class StopState : ICarState
{
    public void Drive(Car car)
    {
        Console.WriteLine($"{car.Name}已啟動(dòng)酱塔,開始自動(dòng)駕駛!");
        car.CurrentCarState = Car.RunState;
    }

    public void Stop(Car car)
    {
        Console.WriteLine("車輛已停止危虱!");
    }

    public void SpeedUp(Car car)
    {
        Console.WriteLine("車輛已停止羊娃!");
    }

    public void SpeedDown(Car car)
    {
        Console.WriteLine("車輛已停止!");
    }
}

加速狀態(tài)也是運(yùn)行狀態(tài)埃跷,可減速或停車蕊玷。

/// <summary>
/// 加速狀態(tài)
/// </summary>
public class SpeedUpState : ICarState
{
    public void Drive(Car car)
    {
        Console.WriteLine("車輛正在自動(dòng)駕駛!");
    }

    public void Stop(Car car)
    {
        Console.WriteLine("車輛已停止弥雹!");
        car.CurrentCarState = Car.StopState;
    }

    public void SpeedUp(Car car)
    {
        Console.WriteLine("車輛正在加速行駛垃帅!");
    }

    public void SpeedDown(Car car)
    {
        Console.WriteLine("路況一般,減速行駛剪勿!");
        car.CurrentCarState = Car.SpeedDownState;
    }
}

減速狀態(tài)也是運(yùn)行狀態(tài)挺智,可加速或停車。

/// <summary>
/// 減速狀態(tài)
/// </summary>
public class SpeedDownState : ICarState
{
    public void Drive(Car car)
    {
        Console.WriteLine("車輛正在自動(dòng)駕駛窗宦!");
    }

    public void Stop(Car car)
    {
        Console.WriteLine("車輛已停止!");
        car.CurrentCarState = Car.StopState;
    }

    public void SpeedUp(Car car)
    {
        Console.WriteLine("路況良好二鳄,加速行駛赴涵!");
        car.CurrentCarState = Car.SpeedUpState;
    }

    public void SpeedDown(Car car)
    {
        Console.WriteLine("車輛正在減速行駛!");
    }
}

定義完?duì)顟B(tài)订讼,下面我們就來(lái)看看實(shí)際的車類髓窜。

public class Car
{
    public string Name { get; set; }

    public Car()
    {
        this.CurrentCarState = StopState;//初始狀態(tài)為停車狀態(tài)
    }

    internal static ICarState StopState = new StopState();
    internal static ICarState RunState = new RuningState();
    internal static ICarState SpeedDownState = new SpeedDownState();
    internal static ICarState SpeedUpState = new SpeedUpState();

    public ICarState CurrentCarState { get; set; }

    public void Run()
    {
        this.CurrentCarState.Drive(this);
    }

    public void Stop()
    {
        this.CurrentCarState.Stop(this);
    }

    public void SpeedUp()
    {
        this.CurrentCarState.SpeedUp(this);
    }
    public void SpeedDown()
    {
        this.CurrentCarState.SpeedDown(this);
    }
}

Car類也比較簡(jiǎn)單,主要是預(yù)先申明并實(shí)例化了幾種狀態(tài)并暴露設(shè)置當(dāng)前狀態(tài)的屬性欺殿,以及提供了狀態(tài)對(duì)應(yīng)的行為方法寄纵,并委托給具體的狀態(tài)去執(zhí)行相應(yīng)的動(dòng)作。

下面就是簡(jiǎn)單的場(chǎng)景類了脖苏。

static void Main(string[] args)
{
    Car tesla = new Car() {Name = "特斯拉 Model S"};
    tesla.Run();
    tesla.SpeedUp();
    tesla.SpeedDown();
    tesla.Stop();

    Console.WriteLine();
}

運(yùn)行結(jié)果

總結(jié):

狀態(tài)模式隱藏了具體的狀態(tài)變化程拭,但行為還是由狀態(tài)變化驅(qū)動(dòng)的。
就狀態(tài)模式而言棍潘,其實(shí)就僅僅三個(gè)角色:

  • State——抽象狀態(tài)角色:接口或抽象類恃鞋,負(fù)責(zé)定義對(duì)象的所有狀態(tài)對(duì)應(yīng)的行為由具體狀態(tài)去實(shí)現(xiàn)。這里對(duì)應(yīng)的是我們定義的ICarState亦歉。
  • ConcreteState——具體狀態(tài)角色:處理當(dāng)前狀態(tài)的行為恤浪,決定是否可以過渡到其他狀態(tài)。這里對(duì)應(yīng)的是我們定義的RunState肴楷、StopState顷扩、SepeedUpState昏鹃、SepeedDownState
  • Context——環(huán)境角色:定義行為偿乖,狀態(tài)轉(zhuǎn)換。這里對(duì)應(yīng)的就是我們的Car類邑狸。

優(yōu)缺點(diǎn):

優(yōu)點(diǎn):結(jié)構(gòu)清晰;符合OCP和SRP;封裝性好圾结。
缺點(diǎn) :在狀態(tài)過多的情況下,會(huì)導(dǎo)致具體狀態(tài)類的膨脹齿诉。

應(yīng)用場(chǎng)景:

  1. 行為隨狀態(tài)改變而改變筝野。
  2. 狀態(tài)已確定,且狀態(tài)不宜過多粤剧。
  3. 重構(gòu)if..elseswitch..case的不二之選歇竟。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市抵恋,隨后出現(xiàn)的幾起案子焕议,更是在濱河造成了極大的恐慌,老刑警劉巖弧关,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盅安,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡世囊,警方通過查閱死者的電腦和手機(jī)别瞭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)株憾,“玉大人蝙寨,你說(shuō)我怎么就攤上這事∴拖梗” “怎么了墙歪?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)贝奇。 經(jīng)常有香客問我虹菲,道長(zhǎng),這世上最難降的妖魔是什么弃秆? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任届惋,我火速辦了婚禮,結(jié)果婚禮上菠赚,老公的妹妹穿的比我還像新娘脑豹。我一直安慰自己,他們只是感情好衡查,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布瘩欺。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俱饿。 梳的紋絲不亂的頭發(fā)上歌粥,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音拍埠,去河邊找鬼失驶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛枣购,可吹牛的內(nèi)容都是我干的嬉探。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼棉圈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼涩堤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起分瘾,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤胎围,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后德召,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體白魂,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年上岗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碧聪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡液茎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辞嗡,到底是詐尸還是另有隱情捆等,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布续室,位于F島的核電站栋烤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏挺狰。R本人自食惡果不足惜明郭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丰泊。 院中可真熱鬧薯定,春花似錦、人聲如沸瞳购。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至年堆,卻和暖如春吞杭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背变丧。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工芽狗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痒蓬。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓童擎,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親谊却。 傳聞我的和親對(duì)象是個(gè)殘疾皇子柔昼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容