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

積木

No sub title

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

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

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


Aka. Token

在不破壞封裝性的前提下,捕獲一個對象的內部狀態,并在該對象之外保存其狀態。這樣以后就可以將該對象恢復到原先保存的狀態。

“Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.” – GoF

動機

有時候需要記錄一個對象的內部狀態。比如要實現checkpoint或者undo這樣的機制,可以讓使用者從臨時性的操作跳出來或者需要修復錯誤的時候,你必須將狀態信息保存在某個地方,以便在進行某些操作后,將對象恢復到原來的狀態。但通常情況下,對象封裝了狀態(即私有成員變量),因此其他的對象無法訪問這些狀態,而且也不可能將這些狀態保存在對象之外。如果將這些狀態設置成公有的,又會違反面向對象封裝性的原則,同時也會削弱應用的可靠性和可擴展性。

在軟件構建過程中, 某些對象的狀態在轉換過程中,可能由于某種需要,要求程序能夠回溯到對象之前處于某個時刻的狀態。如果使用一些共有接口來讓其他對象得到對象的狀態,便會暴露對象的細節實現。Memento設計模式就可以實現對象狀態的良好保存與恢復,但同時又不會因此而破壞對象本身的封裝性。

UML類圖:

21. C++實現Behavioral - Memento模式 - 玄機逸士 - 玄機逸士博客

角色

- Memento

1. 保存Originator對象的內部狀態。

2. Originator外,其他對象均不能訪問Memento對象。

- Originator

1. 創建一個包含其當前內部狀態快照的Memento對象。

2. 使用Memento對象來恢復其內部狀態。

- Caretaker

1. Memento對象的容器。在C++中一般用stack來實現。

2. 從不對Memento對象的內容進行檢查或操作。

示例代碼:

// Memento.h

#include <iostream>

#include <stack>

using namespace std;

// CMemento類,用來保存CRectangle的狀態

class CMemento

{

private: // 所有的成員變量和成員函數都是私有的

int topx; // 因此除友元類CRectangle外,其他對象都無法訪問

int topy;

int width;

int height;

private:

CMemento()

{

}

//private: // 1. 如果編寫了顯式拷貝構造函數,那么,它必須是公有的,

// CMemento(const CMemento& memo) // 否則CMementoStack將無法調用該拷貝構造函數。

// { // 2. 如果沒有顯式的拷貝構造函數,那么缺省的拷貝構造函數總是公有的。

// topx = memo.topx; // 3. Memento模式中,如果僅考慮保存一次狀態,則

// topy = memo.topy; // CMementoStack是不必要的,那么拷貝構造函數,可以

// width = memo.width; // 顯式地聲明為private的,盡管在CRectanglecreate_memento

// height = memo.height; // 成員函數中也會調用CMemento的拷貝構造函數,但CRectangle

// } // CMemento的友元類,因此不存在這方面的限制。

private:

void set_state(int topx, int topy, int width, int height) // 保存CRectangle的狀態

{

this->topx = topx;

this->topy = topy;

this->width = width;

this->height = height;

}

friend class CRectangle; // 友元類CRectangle,可以訪問CMemento中的所有內容

};

// CRectangle類。一個矩形,需要保存狀態改變的類

class CRectangle

{

private:

int topx; // 矩形左上角的x坐標

int topy; // 矩形左上角的y坐標

int width; // 矩形的寬

int height; // 矩形的高

public:

CRectangle(int topx, int topy, int width, int height):topx(topx), topy(topy), width(width), height(height)

{

}

// 模擬移動矩形的位置到指定的點,即改變了矩形的狀態

void move_to(int topx, int topy)

{

this->topx = topx;

this->topy = topy;

}

// 模擬改變矩形的長和寬,即改變了矩形的狀態

void change_width_height(int width, int height)

{

this->width = width;

this->height = height;

}

// 將矩形恢復到memo中所保存的狀態

void set_memento(CMemento memo)

{

this->topx = memo.topx;

this->topy = memo.topy;

this->width = memo.width;

this->height = memo.height;

}

// 將矩形的狀態保存到一個CMemento對象

CMemento create_memento()

{

CMemento cm;

cm.set_state(this->topx, this->topy, this->width, this->height);

return cm;

}

// 輸出矩形的狀態信息

void print_info()

{

cout << "Top left point's x coordinate: " << topx << endl;

cout << "Top left point's y coordinate: " << topy << endl;

cout << "The width is: " << width << endl;

cout << "The height is: " << height << endl;

}

};

// CMemento對象的容器,可以用來保存多個CMemento對象,通常用stack來實現

class CMementoStack

{

private:

stack<CMemento> stk;

public:

void add_memento(CMemento memo)

{

stk.push(memo); //CMemento對象壓入棧中

}

CMemento get_memento()

{

CMemento cm = stk.top(); // 取得CMemento對象。這個過程會用到CMemento類的拷貝構造函數,

// 由于CMemento對象中的成員變量均是普通類型(非指針、非類對象)

// 因此使用默認的拷貝構造函數即可

stk.pop(); // 刪除已經取得的CMemento對象

return cm;

}

};

// Memento.cpp

#include "Memento.h"

int main(int argc, char **argv)

{

CRectangle cr(10, 10, 100, 100);

CMementoStack cs;

cout << "Initial states: " << endl;

cr.print_info();

CMemento cm0 = cr.create_memento(); // 將狀態保存到CMemento對象

cs.add_memento(cm0); // CMemento對象壓棧

// 第一次改變狀態

cr.change_width_height(200, 200); // 改變矩形的高度和寬度

cr.move_to(20, 20); // 改變矩形的位置

cout << "\nAfter 1st states changed: " << endl;

cr.print_info();

CMemento cm1 = cr.create_memento(); // 將狀態保存到CMemento對象

cs.add_memento(cm1); // CMemento對象壓棧

// 第二次改變狀態

cr.change_width_height(300, 300); // 改變矩形的高度和寬度

cr.move_to(30, 30); // 改變矩形的位置

cout << "\nAfter 2nd states changed: " << endl;

cr.print_info();

// ... 這里不再壓棧

// 恢復到第一次狀態的改變

cr.set_memento(cs.get_memento());

cout << "\nStates restored to 1st change: " << endl;

cr.print_info();

// 恢復到初始狀態

cr.set_memento(cs.get_memento());

cout << "\nStates restored to initial: " << endl;

cr.print_info();

}

運行結果:

Initial states:

Top left point's x coordinate: 10

Top left point's y coordinate: 10

The width is: 100

The height is: 100

After 1st states changed:

Top left point's x coordinate: 20

Top left point's y coordinate: 20

The width is: 200

The height is: 200

After 2nd states changed:

Top left point's x coordinate: 30

Top left point's y coordinate: 30

The width is: 300

The height is: 300

States restored to 1st change:

Top left point's x coordinate: 20

Top left point's y coordinate: 20

The width is: 200

The height is: 200

States restored to initial:

Top left point's x coordinate: 10

Top left point's y coordinate: 10

The width is: 100

The height is: 100

結果符合預期。

補充說明:

1. 未設置其成員變量為public的前提下,在對象的外部保存一個其狀態,頗需技巧,而且用不同語言來實現的時候也有所不同。

a. 對于C++,通常使用友元類來實現。

b. 對于C#,使用internal關鍵字。

c. 對于Java,使用package protected訪問控制。

與其處于相同包中的子類,和處于相同包中的其它類均可以訪問pakcage protected的對象或變量。

Java中的訪問權限有public,private,protected和默認的包訪問權限,如果類中的屬性方法沒有顯示的指明訪問權

限,則具有包訪問權限,很多人也稱它為friendly訪問權限,也有人稱為packeged權限,而packagedfriendly

這兩個關鍵字在實際中都是不存在的。在Java中,訪問權限修飾符權限從高到低是public,protected,package

protected,private

d. C++, C#Java均可使用內部類的方式來實現類似的功能,不過對于“將狀態存儲于對象之外”而言,稍嫌勉強。

2. 關于拷貝構造函數,請看:http://patmusing.blog.163.com/blog/static/1358349602009113061024796/

3. 關于友元類,請看:http://patmusing.blog.163.com/blog/static/1358349602010182331153/



posted on 2013-03-08 14:51 Jacc.Kim 閱讀(214) 評論(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>
            欧美在线一区二区| 一区免费观看视频| 一区二区三区视频在线看| 免费欧美高清视频| 久久综合色播五月| 亚洲精品资源美女情侣酒店| 亚洲国产免费| 欧美 日韩 国产精品免费观看| 亚洲国产精品日韩| 亚洲精品中文字幕女同| 国产精品成人免费| 久久久久久夜| 欧美成人乱码一区二区三区| 宅男在线国产精品| 午夜视频在线观看一区| 在线精品国产欧美| 亚洲免费av片| 国内精品久久久久影院优 | 国产精品美女久久| 久久xxxx| 欧美麻豆久久久久久中文| 欧美一区二区三区电影在线观看| 欧美中文字幕视频| 99riav国产精品| 欧美亚洲在线播放| 99re6热只有精品免费观看| 亚洲午夜女主播在线直播| 精品成人在线视频| 一本不卡影院| 亚洲国产成人午夜在线一区| 一区二区日韩免费看| 永久免费视频成人| 亚洲一区二区三| 亚洲精品国精品久久99热| 亚洲欧美在线aaa| 一区二区三区四区五区视频| 欧美一区二区三区日韩| 一区二区三区国产在线| 久久琪琪电影院| 午夜在线电影亚洲一区| 欧美精品久久久久久久| 久久夜色撩人精品| 国产精品视频成人| 亚洲人人精品| 亚洲风情亚aⅴ在线发布| 午夜精品久久久久久久| 亚洲无人区一区| 欧美黄网免费在线观看| 美女脱光内衣内裤视频久久网站| 国产精品毛片一区二区三区| 亚洲欧洲三级| 亚洲日本中文字幕| 久久一区欧美| 老司机午夜精品视频| 国产亚洲一级| 欧美一区二区三区另类| 亚洲综合国产| 欧美三区免费完整视频在线观看| 欧美激情综合| 91久久精品国产91久久| 久久亚洲一区二区| 久久综合网色—综合色88| 国产亚洲激情| 久久精品99久久香蕉国产色戒| 欧美一区二区三区在线| 国产精品嫩草99av在线| 亚洲一区二区三区视频播放| 欧美一区成人| 国产精品一区二区三区观看| 亚洲女优在线| 欧美在线视频一区二区| 国产亚洲精品bv在线观看| 欧美一区永久视频免费观看| 久久精品国产精品亚洲精品| 国产视频一区二区在线观看| 欧美一区成人| 欧美freesex8一10精品| 亚洲人成人一区二区在线观看| 鲁大师影院一区二区三区| 欧美激情乱人伦| 99成人在线| 国产精品免费区二区三区观看| 午夜免费在线观看精品视频| 久久偷看各类wc女厕嘘嘘偷窃| 影音先锋久久| 欧美日韩不卡视频| 亚洲综合第一页| 老司机精品久久| 99视频在线精品国自产拍免费观看| 欧美日韩免费看| 午夜精品久久久久影视| 免费不卡视频| 亚洲视频在线二区| 国产午夜精品久久| 免费影视亚洲| 亚洲在线播放电影| 欧美成人xxx| 亚洲综合激情| 亚洲国产精品成人久久综合一区| 欧美日本在线看| 欧美一区二区三区播放老司机| 亚洲国产精品va在线看黑人动漫| 亚洲欧美欧美一区二区三区| 激情av一区二区| 欧美三级午夜理伦三级中视频| 久久精品亚洲一区二区| 亚洲黄一区二区| 久久国产欧美日韩精品| 亚洲美女91| 狠狠做深爱婷婷久久综合一区| 欧美日韩成人综合在线一区二区| 久久gogo国模裸体人体| 日韩一二在线观看| 你懂的成人av| 欧美制服丝袜第一页| 亚洲免费电影在线| 伊人久久成人| 国产伦精品一区二区三区免费| 欧美国产一区二区三区激情无套| 亚洲欧美国产精品va在线观看| 亚洲激情欧美激情| 麻豆av一区二区三区| 午夜亚洲福利| 亚洲婷婷免费| 亚洲免费高清视频| 激情久久久久| 国产一区二区三区电影在线观看| 欧美日韩午夜激情| 欧美精品高清视频| 免费成人你懂的| 久久精品中文字幕一区| 香蕉av777xxx色综合一区| 亚洲最快最全在线视频| 亚洲国产精品电影在线观看| 老司机67194精品线观看| 久久se精品一区精品二区| 亚洲欧美日韩专区| 亚洲欧美成aⅴ人在线观看| 亚洲美女中文字幕| 亚洲狼人综合| 亚洲精品人人| 99视频精品在线| 99这里只有精品| 一本色道久久综合亚洲精品婷婷 | 国产一区二区日韩精品| 国产精品一卡| 国产日韩欧美日韩| 国产一区二区精品在线观看| 国产精品一区二区在线观看| 国产精品欧美精品| 国产女优一区| 国产综合色产在线精品| 国产综合色在线| 樱桃国产成人精品视频| 亚洲欧美美女| 亚洲欧美一区二区三区久久| 亚洲欧美在线视频观看| 久久精品国产精品| 免费国产自线拍一欧美视频| 欧美精品电影| 国产精品激情av在线播放| 国产精品视频精品| 精品51国产黑色丝袜高跟鞋| 亚洲国产小视频在线观看| 亚洲精品网站在线播放gif| 一区二区三区欧美在线| 亚洲视频一区| 久久久精品2019中文字幕神马| 久久婷婷久久| 亚洲九九精品| 欧美一区二区在线视频| 美国成人毛片| 国产精品大片| 国产日韩欧美综合| 91久久国产自产拍夜夜嗨| 99re6这里只有精品| 亚洲欧美成人一区二区三区| 久久午夜羞羞影院免费观看| 91久久国产综合久久蜜月精品| 日韩午夜电影av| 欧美一区在线直播| 欧美精品偷拍| 国内精品美女av在线播放| 99综合精品| 久久精品国产第一区二区三区| 欧美成人精品在线视频| 中日韩美女免费视频网站在线观看| 欧美一区二区三区视频在线| 欧美高潮视频| 黄色一区二区在线| 亚洲一区二区在线| 久久久久.com| 亚洲裸体视频| 美女脱光内衣内裤视频久久影院 | 国产精品日韩一区| 亚洲巨乳在线| 欧美成va人片在线观看| 午夜精品久久久久久久男人的天堂 | 亚洲一区二区免费| 欧美国产一区二区三区激情无套|