• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            積木

            No sub title

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              140 Posts :: 1 Stories :: 11 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(1)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            轉(zhuǎn)載自:http://patmusing.blog.163.com/blog/static/13583496020101502024824/


            也稱為
            Objects for States模式。

            允許一個對象在其內(nèi)部狀態(tài)改變時改變其行為,從而使對象看起來似乎修改了類。

            “Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.” – GoF

            一個應(yīng)用的行為往往會根據(jù)其內(nèi)部變量值而表現(xiàn)出很大的不同。比如用Visual Studio開發(fā)程序,當寫了一段程序后,如果點擊保存的按鈕,則所寫的程序便保存到了硬盤上,然后保存按鈕變灰,這時候程序文件時saved的狀態(tài);在這個狀態(tài)上,如果有加了幾行代碼,那么狀態(tài)就變成unsaved,此時,保存按鈕又可以點擊。savedunsaved是程序文件的狀態(tài),保存這個動作是行為,對于saved或者unsaved,同樣的保存動作有不同的意義,即,如果程序文件時saved的狀態(tài),那么點擊保存按鈕,則什么也不做(按鈕式灰色的);如果程序文件時unsaved狀態(tài),點擊保存按鈕,則保存程序文件。這個案例說明,對象的狀態(tài)和其行為有密切的關(guān)系。

            要解決類似上面的問題,通常的做法:

            1. 設(shè)置一個狀態(tài)變量

            2. switch – case或者if – else – if這樣的辦法來判定對象的狀態(tài),然后根據(jù)所得到的狀態(tài),選擇不同行為

            如果增加了一個狀態(tài),那么

            1. 增加一個狀態(tài)變量

            2. 修改switch – case或者if – else – if語句,這顯然不符合OCP的原則(這里會增加編譯的時間成本),也沒有把程序變化部分和相對穩(wěn)定的部分隔離開,這會削弱應(yīng)用程序的可擴展性

            State模式就是為了解決上面的問題而產(chǎn)生的。即專門處理當對象處于不同的狀態(tài)時,將會有不同的行為這樣的情況。

            State模式的UML類圖如下:

            23. C++實現(xiàn)Behavioral - State模式 - 玄機逸士 - 玄機逸士博客

            考慮一個門的狀態(tài):

            23. C++實現(xiàn)Behavioral - State模式 - 玄機逸士 - 玄機逸士博客

            說明:

            如果一個門處于Opened狀態(tài),那么對其施加close動作,就會使門的狀態(tài)變成Closed的狀態(tài);

            如果一個門處于Opened狀態(tài),那么對其施加open動作,那么門的狀態(tài)不會改變,依舊是Opened的狀態(tài);

            如果一個門處于Closed狀態(tài),那么對其施加open動作,就會使門的狀態(tài)變成Opened的狀態(tài);

            如果一個門處于Closed狀態(tài),那么對其施加close動作,那么門的狀態(tài)不會改變,依舊是Closed的狀態(tài);

            下面用State模式具體實現(xiàn)上面業(yè)務(wù)的C++代碼:

            // State.h

            #include <iostream>

            #include <string>

            #include <typeinfo>

            #include <memory>

            using namespace std;

            // 前置聲明

            class Door;

            // 門的狀態(tài)

            class DoorState

            {

            public:

            virtual ~DoorState();

            public:

            virtual void open(Door* door) = 0; // 開門

            virtual void close(Door* door) = 0; // 關(guān)門

            };

            // 打開狀態(tài)的門

            class DoorOpened : public DoorState

            {

            public:

            ~DoorOpened();

            public:

            void open(Door* door);

            void close(Door* door);

            };

            // 關(guān)閉狀態(tài)的門

            class DoorClosed : public DoorState

            {

            public:

            ~DoorClosed();

            public:

            void open(Door* door);

            void close(Door* door);

            };

            //

            class Door

            {

            private:

            auto_ptr<DoorState> door_state; // 門的狀態(tài)

            public:

            Door();

            ~Door();

            public:

            void open(); // 開門

            void close(); // 關(guān)門

            void set_state(auto_ptr<DoorState> door_state); // 設(shè)置門的狀態(tài)

            string get_state(); // 獲取門的狀態(tài)

            };

            // State.cpp

            #include "State.h"

            DoorState::~DoorState()

            {

            cout << "in the destructor of DoorState..." << endl;

            }

            DoorOpened::~DoorOpened()

            {

            cout << "in the destructor of DoorOpened..." << endl;

            }

            // 如果門已經(jīng)是打開的狀態(tài),則僅輸出相關(guān)信息

            void DoorOpened::open(Door* door)

            {

            cout << "The Door is already opened. State will not change..." << endl;

            }

            // 如果門是關(guān)閉的狀態(tài),則關(guān)門

            void DoorOpened::close(Door* door)

            {

            auto_ptr<DoorState> ds(new DoorClosed());

            door->set_state(ds);

            }

            DoorClosed::~DoorClosed()

            {

            cout << "in the destructor of DoorClosed..." << endl;

            }

            // 如果門是關(guān)閉的狀態(tài),則開門

            void DoorClosed::open(Door* door)

            {

            auto_ptr<DoorState> ds(new DoorOpened());

            door->set_state(ds);

            }

            // 如果門已經(jīng)是關(guān)閉的狀態(tài),則僅輸出相關(guān)信息

            void DoorClosed::close(Door* door)

            {

            cout << "The Door is already closed. State will not change..." << endl;

            }

            Door::Door()

            {

            auto_ptr<DoorState> ds(new DoorOpened()); // 設(shè)定門的初始狀態(tài)

            door_state = ds;

            }

            Door::~Door()

            {

            cout << "in the destructor of Door..." << endl;

            }

            void Door::open() // 開門

            {

            door_state->open(this);

            }

            void Door::close() // 關(guān)門

            {

            door_state->close(this);

            }

            void Door::set_state(auto_ptr<DoorState> door_state) // 設(shè)定門的狀態(tài)

            {

            this->door_state = door_state;

            }

            // 利用RTTI技術(shù),輸出門的狀態(tài)

            string Door::get_state()

            { // *(door_state.get())*(door_state)的寫法是等價的,get()表示獲取auto_ptr對象中underlying對象的真實指針,因此語

            // 法上顯得更好理解一些。但*auto_ptr中也被重載過了,因此兩者的結(jié)果是一樣的。

            string temp = typeid(*(door_state.get())).name(); // temp將等于 "class DoorOpened""class DoorClosed"

            size_t found = temp.find("Door"); // 找到"Door"temp中位置

            temp = temp.substr(found + 4); // 去掉"Door"(包括其自身)前面的字符串

            return temp;

            }

            // PatternClient.cpp

            #include "State.h"

            int main(int argc, char** argv)

            {

            Door door;

            cout << "1. Initial state of the door: " << door.get_state() << endl;

            cout << "------------------------------------------------------" << endl;

            cout << endl;

            door.open();

            cout << "2. State after opening the door: " << door.get_state() << endl;

            cout << "------------------------------------------------------" << endl;

            cout << endl;

            door.close();

            cout << "3. State after closing the door: " << door.get_state() << endl;

            cout << "------------------------------------------------------" << endl;

            cout << endl;

            door.close();

            cout << "4. State after closing the door: " << door.get_state() << endl;

            cout << "------------------------------------------------------" << endl;

            cout << endl;

            door.open();

            cout << "5. State after opening the door: " << door.get_state() << endl;

            cout << "------------------------------------------------------" << endl;

            cout << endl;

            return 0;

            }

            輸出結(jié)果:

            1. Initial state of the door: Opened

            ------------------------------------------------------

            The Door is already opened. State will not change...

            2. State after opening the door: Opened

            ------------------------------------------------------

            in the destructor of DoorOpened...

            in the destructor of DoorState...

            3. State after closing the door: Closed

            ------------------------------------------------------

            The Door is already closed. State will not change...

            4. State after closing the door: Closed

            ------------------------------------------------------

            in the destructor of DoorClosed...

            in the destructor of DoorState...

            5. State after opening the door: Opened

            ------------------------------------------------------

            in the destructor of Door...

            in the destructor of DoorOpened...

            in the destructor of DoorState...

            上面程序的UML類圖如下:

            23. C++實現(xiàn)Behavioral - State模式 - 玄機逸士 - 玄機逸士博客

            要點:

            - State設(shè)計模式將一個特定狀態(tài)相關(guān)的行為都放入一個State的子類對象中,在對象狀態(tài)切換時,切換相應(yīng)的對象;但同時維持State的接口穩(wěn)定,這樣實現(xiàn)了具體操作與狀態(tài)轉(zhuǎn)換之間的解耦。

            - 為不同的狀態(tài)引入不同的對象,使得一個狀態(tài)和一個對象一一對應(yīng),這也是為什么這個模式也稱為Objects for States的原因。這使得狀態(tài)轉(zhuǎn)換變得更加明確,而且可以保證不會出現(xiàn)狀態(tài)不一致的情況,因為對象的狀態(tài)是由一個類來表示的,那么就保證了狀態(tài)轉(zhuǎn)換的原子性 即要么轉(zhuǎn)換成功,要不轉(zhuǎn)換 (即上面示例程序中的door_state要么被設(shè)定為DoorOpened,要么被設(shè)定為DoorClosed。如果一個對象有很多狀態(tài),采用通常的方法會有很復(fù)雜的if-else if-else語句,維護這些復(fù)雜的語句,很有可能導(dǎo)致各種麻煩,其中之一就是狀態(tài)的不一致。)

            - State模式和Strategy模式很類似。它們最主要的區(qū)別就是:State模式是用不同的對象去封裝不同的狀態(tài),而Stategy模式用不同的對象去封裝不同的算法。

            參考:

            1. auto_ptr的用途和原理,詳見:http://patmusing.blog.163.com/blog/static/13583496020101824142699/

            2. 使用auto_ptr的注意事項,詳見:http://patmusing.blog.163.com/blog/static/13583496020101824541270/

            3. 關(guān)于RTTI,詳見Stan Lippman的《C++ Primer》第4版之第18



            posted on 2013-03-08 15:24 Jacc.Kim 閱讀(285) 評論(0)  編輯 收藏 引用 所屬分類: 設(shè)計模式
            久久久久久久人妻无码中文字幕爆| 久久婷婷五月综合色奶水99啪| 久久国产精品一区二区| 欧美日韩成人精品久久久免费看| 91精品久久久久久无码| 思思久久精品在热线热| 久久国产福利免费| 中文字幕无码久久久| 久久国产乱子精品免费女| 久久精品桃花综合| 久久久久久久波多野结衣高潮| 一本色道久久88加勒比—综合| 久久久久亚洲精品日久生情 | 婷婷久久综合| 老司机午夜网站国内精品久久久久久久久 | 精品无码久久久久久国产| 国内精品久久国产| 久久久久国产精品嫩草影院| 久久精品国产男包| 无码国产69精品久久久久网站| 国产成人久久精品一区二区三区| 午夜精品久久久久久| 亚洲综合久久夜AV | 亚洲AV无一区二区三区久久| 久久久精品免费国产四虎| 国产精品欧美亚洲韩国日本久久| 久久久久亚洲AV成人网人人网站 | 国产精品久久久久蜜芽| 亚洲精品乱码久久久久久蜜桃不卡 | 久久丝袜精品中文字幕| 香蕉久久影院| 久久国产亚洲精品麻豆| 色婷婷综合久久久中文字幕| 国产亚洲美女精品久久久久狼| 久久精品国产一区二区三区不卡 | 国产精品免费看久久久香蕉| 国产精品久久久久免费a∨| 久久久WWW成人免费精品| 久久99精品久久久久久久久久| 久久男人中文字幕资源站| 国产ww久久久久久久久久|