日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

设计模式C++实现(9)——享元模式

發(fā)布時(shí)間:2025/3/20 c/c++ 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式C++实现(9)——享元模式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ?軟件領(lǐng)域中的設(shè)計(jì)模式為開(kāi)發(fā)人員提供了一種使用專家設(shè)計(jì)經(jīng)驗(yàn)的有效途徑。設(shè)計(jì)模式中運(yùn)用了面向?qū)ο缶幊陶Z(yǔ)言的重要特性:封裝、繼承、多態(tài),真正領(lǐng)悟設(shè)計(jì)模式的精髓是可能一個(gè)漫長(zhǎng)的過(guò)程,需要大量實(shí)踐經(jīng)驗(yàn)的積累。最近看設(shè)計(jì)模式的書,對(duì)于每個(gè)模式,用C++寫了個(gè)小例子,加深一下理解。主要參考《大話設(shè)計(jì)模式》和《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》(DP)兩本書。本文介紹享元模式的實(shí)現(xiàn)。

??????? 舉個(gè)圍棋的例子,圍棋的棋盤共有361格,即可放361個(gè)棋子。現(xiàn)在要實(shí)現(xiàn)一個(gè)圍棋程序,該怎么辦呢?首先要考慮的是棋子棋盤的實(shí)現(xiàn),可以定義一個(gè)棋子的類,成員變量包括棋子的顏色、形狀、位置等信息,另外再定義一個(gè)棋盤的類,成員變量中有個(gè)容器,用于存放棋子的對(duì)象。下面給出代碼表示:

????????棋子的定義,當(dāng)然棋子的屬性除了顏色和位置,還有其他的,這里略去。這兩個(gè)屬性足以說(shuō)明問(wèn)題。

[cpp]?view plaincopy print?
  • //棋子顏色??
  • enum?PieceColor?{BLACK,?WHITE};??
  • //棋子位置??
  • struct?PiecePos??
  • {??
  • ????int?x;??
  • ????int?y;??
  • ????PiecePos(int?a,?int?b):?x(a),?y(b)?{}??
  • };??
  • //棋子定義??
  • class?Piece??
  • {??
  • protected:??
  • ????PieceColor?m_color;?//顏色??
  • ????PiecePos?m_pos;?????//位置??
  • public:??
  • ????Piece(PieceColor?color,?PiecePos?pos):?m_color(color),?m_pos(pos)?{}??
  • ????~Piece()?{}??
  • ????virtual?void?Draw()?{}??
  • };??
  • class?BlackPiece:?public?Piece??
  • {??
  • public:??
  • ????BlackPiece(PieceColor?color,?PiecePos?pos):?Piece(color,?pos)?{}??
  • ????~BlackPiece()?{}??
  • ????void?Draw()?{?cout<<"繪制一顆黑棋"<<endl;}??
  • };??
  • class?WhitePiece:?public?Piece??
  • {??
  • public:??
  • ????WhitePiece(PieceColor?color,?PiecePos?pos):?Piece(color,?pos)?{}??
  • ????~WhitePiece()?{}??
  • ????void?Draw()?{?cout<<"繪制一顆白棋"<<endl;}??
  • };??
  • ????????棋盤的定義:

    [cpp]?view plaincopy print?
  • class?PieceBoard??
  • {??
  • private:??
  • ????vector<Piece*>?m_vecPiece;?//棋盤上已有的棋子??
  • ????string?m_blackName;?//黑方名稱??
  • ????string?m_whiteName;?//白方名稱??
  • public:??
  • ????PieceBoard(string?black,?string?white):?m_blackName(black),?m_whiteName(white){}??
  • ????~PieceBoard()?{?Clear();?}??
  • ????void?SetPiece(PieceColor?color,?PiecePos?pos)?//一步棋,在棋盤上放一顆棋子??
  • ????{??
  • ????????Piece?*?piece?=?NULL;??
  • ????????if(color?==?BLACK)?//黑方下的??
  • ????????{?????
  • ????????????piece?=?new?BlackPiece(color,?pos);?//獲取一顆黑棋??
  • ????????????cout<<m_blackName<<"在位置("<<pos.x<<','<<pos.y<<")";??
  • ????????????piece->Draw();?//在棋盤上繪制出棋子??
  • ????????}??
  • ????????else??
  • ????????{?????
  • ????????????piece?=?new?WhitePiece(color,?pos);??
  • ????????????cout<<m_whiteName<<"在位置("<<pos.x<<','<<pos.y<<")";??
  • ????????????piece->Draw();??
  • ????????}??
  • ????????m_vecPiece.push_back(piece);??//加入容器中??
  • ????}??
  • ????void?Clear()?//釋放內(nèi)存??
  • ????{??
  • ????????int?size?=?m_vecPiece.size();??
  • ????????for(int?i?=?0;?i?<?size;?i++)??
  • ????????????delete?m_vecPiece[i];??
  • ????}??
  • };??
  • ????????客戶的使用方式如下:

    [cpp]?view plaincopy print?
  • int?main()??
  • {??
  • ????PieceBoard?pieceBoard("A","B");??
  • ????pieceBoard.SetPiece(BLACK,?PiecePos(4,?4));??
  • ????pieceBoard.SetPiece(WHITE,?PiecePos(4,?16));??
  • ????pieceBoard.SetPiece(BLACK,?PiecePos(16,?4));??
  • ????pieceBoard.SetPiece(WHITE,?PiecePos(16,?16));??
  • }??
  • ???????可以發(fā)現(xiàn),棋盤的容器中存放了已下的棋子,而每個(gè)棋子包含棋子的所有屬性。一盤棋往往需要含上百顆棋子,采用上面這種實(shí)現(xiàn),占用的空間太大了。如何改進(jìn)呢?用享元模式。其定義為:運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象。

    ????????在圍棋中,棋子就是大量細(xì)粒度的對(duì)象。其屬性有內(nèi)在的,比如顏色、形狀等,也有外在的,比如在棋盤上的位置。內(nèi)在的屬性是可以共享的,區(qū)分在于外在屬性。因此,可以這樣設(shè)計(jì),只需定義兩個(gè)棋子的對(duì)象,一顆黑棋和一顆白棋,這兩個(gè)對(duì)象含棋子的內(nèi)在屬性;棋子的外在屬性,即在棋盤上的位置可以提取出來(lái),存放在單獨(dú)的容器中。相比之前的方案,現(xiàn)在容器中僅僅存放了位置屬性,而原來(lái)則是棋子對(duì)象。顯然,現(xiàn)在的方案大大減少了對(duì)于空間的需求。

    ? ? ? ?關(guān)注PieceBoard 的容器,之前是vector<Piece*> m_vecPiece,現(xiàn)在是vector<PiecePos> m_vecPos。這里是關(guān)鍵。

    ???????棋子的新定義,只包含內(nèi)在屬性:

    [cpp]?view plaincopy print?
  • //棋子顏色??
  • enum?PieceColor?{BLACK,?WHITE};??
  • //棋子位置??
  • struct?PiecePos??
  • {??
  • ????int?x;??
  • ????int?y;??
  • ????PiecePos(int?a,?int?b):?x(a),?y(b)?{}??
  • };??
  • //棋子定義??
  • class?Piece??
  • {??
  • protected:??
  • ????PieceColor?m_color;?//顏色??
  • public:??
  • ????Piece(PieceColor?color):?m_color(color)?{}??
  • ????~Piece()?{}??
  • ????virtual?void?Draw()?{}??
  • };??
  • class?BlackPiece:?public?Piece??
  • {??
  • public:??
  • ????BlackPiece(PieceColor?color):?Piece(color)?{}??
  • ????~BlackPiece()?{}??
  • ????void?Draw()?{?cout<<"繪制一顆黑棋\n";?}??
  • };??
  • class?WhitePiece:?public?Piece??
  • {??
  • public:??
  • ????WhitePiece(PieceColor?color):?Piece(color)?{}??
  • ????~WhitePiece()?{}??
  • ????void?Draw()?{?cout<<"繪制一顆白棋\n";}??
  • };??
  • ????????相應(yīng)棋盤的定義為:

    [cpp]?view plaincopy print?
  • class?PieceBoard??
  • {??
  • private:??
  • ????vector<PiecePos>?m_vecPos;?//存放棋子的位置??
  • ????Piece?*m_blackPiece;???????//黑棋棋子???
  • ????Piece?*m_whitePiece;???????//白棋棋子??
  • ????string?m_blackName;??
  • ????string?m_whiteName;??
  • public:??
  • ????PieceBoard(string?black,?string?white):?m_blackName(black),?m_whiteName(white)??
  • ????{??
  • ????????m_blackPiece?=?NULL;??
  • ????????m_whitePiece?=?NULL;??
  • ????}??
  • ????~PieceBoard()?{?delete?m_blackPiece;?delete?m_whitePiece;}??
  • ????void?SetPiece(PieceColor?color,?PiecePos?pos)??
  • ????{??
  • ????????if(color?==?BLACK)??
  • ????????{??
  • ????????????if(m_blackPiece?==?NULL)??//只有一顆黑棋??
  • ????????????????m_blackPiece?=?new?BlackPiece(color);?????
  • ????????????cout<<m_blackName<<"在位置("<<pos.x<<','<<pos.y<<")";??
  • ????????????m_blackPiece->Draw();??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????if(m_whitePiece?==?NULL)??
  • ????????????????m_whitePiece?=?new?WhitePiece(color);??
  • ????????????cout<<m_whiteName<<"在位置("<<pos.x<<','<<pos.y<<")";??
  • ????????????m_whitePiece->Draw();??
  • ????????}??
  • ????????m_vecPos.push_back(pos);??
  • ????}??
  • };??
  • ???????客戶的使用方式一樣,這里不重復(fù)給出,現(xiàn)在給出享元模式的UML圖,以圍棋為例。棋盤中含兩個(gè)共享的對(duì)象,黑棋子和白棋子,所有棋子的外在屬性都存放在單獨(dú)的容器中。

    ??

    總結(jié)

    以上是生活随笔為你收集整理的设计模式C++实现(9)——享元模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。