青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

積木

No sub title

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

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

轉載自:http://patmusing.blog.163.com/blog/static/13583496020101502024824/


也稱為
Objects for States模式。

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

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

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

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

1. 設置一個狀態變量

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

如果增加了一個狀態,那么

1. 增加一個狀態變量

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

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

State模式的UML類圖如下:

23. C++實現Behavioral - State模式 - 玄機逸士 - 玄機逸士博客

考慮一個門的狀態:

23. C++實現Behavioral - State模式 - 玄機逸士 - 玄機逸士博客

說明:

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

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

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

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

下面用State模式具體實現上面業務的C++代碼:

// State.h

#include <iostream>

#include <string>

#include <typeinfo>

#include <memory>

using namespace std;

// 前置聲明

class Door;

// 門的狀態

class DoorState

{

public:

virtual ~DoorState();

public:

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

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

};

// 打開狀態的門

class DoorOpened : public DoorState

{

public:

~DoorOpened();

public:

void open(Door* door);

void close(Door* door);

};

// 關閉狀態的門

class DoorClosed : public DoorState

{

public:

~DoorClosed();

public:

void open(Door* door);

void close(Door* door);

};

//

class Door

{

private:

auto_ptr<DoorState> door_state; // 門的狀態

public:

Door();

~Door();

public:

void open(); // 開門

void close(); // 關門

void set_state(auto_ptr<DoorState> door_state); // 設置門的狀態

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

};

// State.cpp

#include "State.h"

DoorState::~DoorState()

{

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

}

DoorOpened::~DoorOpened()

{

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

}

// 如果門已經是打開的狀態,則僅輸出相關信息

void DoorOpened::open(Door* door)

{

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

}

// 如果門是關閉的狀態,則關門

void DoorOpened::close(Door* door)

{

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

door->set_state(ds);

}

DoorClosed::~DoorClosed()

{

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

}

// 如果門是關閉的狀態,則開門

void DoorClosed::open(Door* door)

{

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

door->set_state(ds);

}

// 如果門已經是關閉的狀態,則僅輸出相關信息

void DoorClosed::close(Door* door)

{

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

}

Door::Door()

{

auto_ptr<DoorState> ds(new DoorOpened()); // 設定門的初始狀態

door_state = ds;

}

Door::~Door()

{

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

}

void Door::open() // 開門

{

door_state->open(this);

}

void Door::close() // 關門

{

door_state->close(this);

}

void Door::set_state(auto_ptr<DoorState> door_state) // 設定門的狀態

{

this->door_state = door_state;

}

// 利用RTTI技術,輸出門的狀態

string Door::get_state()

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

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

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;

}

輸出結果:

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++實現Behavioral - State模式 - 玄機逸士 - 玄機逸士博客

要點:

- State設計模式將一個特定狀態相關的行為都放入一個State的子類對象中,在對象狀態切換時,切換相應的對象;但同時維持State的接口穩定,這樣實現了具體操作與狀態轉換之間的解耦。

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

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

參考:

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

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

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



posted on 2013-03-08 15:24 Jacc.Kim 閱讀(294) 評論(0)  編輯 收藏 引用 所屬分類: 設計模式
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            1024欧美极品| 亚洲国产视频一区| 亚洲综合色丁香婷婷六月图片| 亚洲日韩中文字幕在线播放| 欧美成人精品激情在线观看| 亚洲精品久久视频| 欧美国产日韩一区| 欧美激情一区二区三区在线视频观看| 亚洲精品视频在线观看网站 | 欧美日韩国产bt| 亚洲免费电影在线观看| 亚洲精品欧美| 国产日韩欧美视频| 免费观看成人| 欧美女同视频| 久久精彩视频| 欧美精品18+| 欧美在线亚洲在线| 美脚丝袜一区二区三区在线观看| 亚洲美女色禁图| 亚洲资源av| 亚洲国产高清在线观看视频| 一本久道久久久| 韩国成人福利片在线播放| 欧美激情精品久久久久久大尺度| 欧美三级网址| 麻豆国产精品一区二区三区 | 免费精品视频| 午夜宅男久久久| 免费观看成人网| 性做久久久久久免费观看欧美| 久久视频一区二区| 亚洲一级片在线观看| 欧美一区日本一区韩国一区| 日韩网站在线看片你懂的| 欧美一级夜夜爽| 国产精品99久久不卡二区 | 亚洲国产一区二区a毛片| 国产精品免费看片| 亚洲激情av| 激情久久中文字幕| 亚洲一区在线看| 一区二区欧美精品| 久久精品一区二区三区四区| 亚洲欧美日韩在线观看a三区| 久久久中精品2020中文| 小黄鸭视频精品导航| 免费观看欧美在线视频的网站| 久久激情网站| 国产精品盗摄一区二区三区| 亚洲国产视频一区| 黄色精品一区二区| 午夜精品福利视频| 香蕉av777xxx色综合一区| 欧美激情日韩| 亚洲第一精品在线| 狠狠色综合色综合网络| 亚洲欧美日韩视频二区| 亚洲综合激情| 国产精品久久久久一区二区三区| 日韩亚洲欧美一区二区三区| 亚洲人体1000| 美女精品在线观看| 欧美jizzhd精品欧美喷水| 国产自产女人91一区在线观看| 亚洲一级二级| 欧美亚洲免费在线| 国产麻豆91精品| 午夜精品国产更新| 久久精品视频在线| 国产综合在线视频| 久久精品30| 乱人伦精品视频在线观看| 一区在线观看| 欧美成人日韩| 99re66热这里只有精品4| 亚洲视频一二区| 国产精品男人爽免费视频1| 亚洲一区成人| 久久天天躁狠狠躁夜夜av| 今天的高清视频免费播放成人| 久久久久久久久一区二区| 裸体歌舞表演一区二区| 亚洲国产精品t66y| 欧美精品v日韩精品v国产精品 | 欧美黑人多人双交| 日韩视频二区| 欧美日韩成人一区| 亚洲一区中文| 欧美sm视频| 国产精品99久久久久久人| 国产精品人人爽人人做我的可爱 | 日韩天堂av| 香蕉免费一区二区三区在线观看| 黑人一区二区| 欧美精品系列| 欧美一二三区精品| 亚洲第一天堂av| 亚洲欧美文学| 亚洲激情啪啪| 国产精品亚洲人在线观看| 久久久久久久一区| 一本久道综合久久精品| 蜜臀91精品一区二区三区| 一区二区三区日韩| 国产日韩亚洲欧美综合| 欧美激情视频在线免费观看 欧美视频免费一| 亚洲精品免费网站| 久久精品国产一区二区三| 亚洲啪啪91| 国产一区二区三区直播精品电影 | 夜夜夜精品看看| 国产亚洲精品v| 欧美美女bb生活片| 欧美一区二区三区在线观看视频| 亚洲高清电影| 久久精品亚洲精品国产欧美kt∨| 日韩视频在线一区二区三区| 狠狠色狠狠色综合日日五| 欧美午夜免费电影| 欧美fxxxxxx另类| 久久精品91久久久久久再现| 亚洲小说欧美另类社区| 亚洲黄色成人久久久| 久久人人97超碰国产公开结果| 亚洲视频一区二区| 亚洲国产日韩综合一区| 国外成人网址| 国产精品手机视频| 欧美日韩在线免费| 欧美成人精品三级在线观看| 久久久久久国产精品mv| 欧美一级视频| 亚洲在线观看| 在线一区免费观看| 亚洲精品一区中文| 最新精品在线| 亚洲国产专区| 亚洲国产成人av| 欧美国产视频在线| 欧美/亚洲一区| 免费成人在线观看视频| 玖玖玖国产精品| 久久夜色精品亚洲噜噜国产mv | 欧美一区国产二区| 亚洲欧美成人网| 午夜精品久久久久久久99热浪潮| 在线亚洲成人| 亚洲尤物在线视频观看| 亚洲欧美在线播放| 亚洲欧美日韩综合| 亚洲欧美综合精品久久成人| 欧美亚洲三级| 久久久久一本一区二区青青蜜月| 久久久久国产精品人| 久久精品午夜| 欧美国产成人精品| 亚洲韩国青草视频| 9l视频自拍蝌蚪9l视频成人| 亚洲五月婷婷| 久久精品国产第一区二区三区最新章节 | 欧美三区在线| 国产人久久人人人人爽| 国内久久视频| 亚洲人成77777在线观看网| 亚洲麻豆国产自偷在线| 一区二区三区国产在线| 午夜视频一区在线观看| 久久久久久黄| 亚洲高清123| 亚洲久久在线| 亚洲欧美在线x视频| 久久婷婷国产综合国色天香| 欧美另类人妖| 国产免费一区二区三区香蕉精| 国产综合久久久久久鬼色| 最新日韩欧美| 亚洲欧美精品伊人久久| 另类天堂视频在线观看| 亚洲日本aⅴ片在线观看香蕉| 亚洲一区在线播放| 久久久久久久久久看片| 欧美午夜精品| 一区免费观看视频| 亚洲在线播放电影| 免费日韩av片| 亚洲淫性视频| 欧美精品123区| 一区在线播放视频| 亚洲女同同性videoxma| 鲁大师成人一区二区三区| 一本大道久久a久久精二百| 久久久综合网站| 国产精品最新自拍| 亚洲啪啪91| 老司机成人在线视频| 亚洲一区免费看| 欧美日韩视频在线一区二区| 亚洲国产天堂久久综合网| 久久久www|