(C++设计模式) ------享元模式-- 结构型模式

(C++设计模式) ------享元模式-- 结构型模式

设计模式的学习是一个循序渐进的过程,每一个设计师都是在套用这几种设计模式来实现自己的软件构架,很多都是融合会贯通的,一个设计模式中不仅仅是用到一种,所以要灵活运用这些设计模式。理解了设计模式对设计和代码的阅读都有很大的好处!!

今天我们学习结构性模式享元(flyweight)模式;

        Flyweight—每天跟MM发短信,手指都累死了,最近买了个新手机,可以把一些常用的句子存在手机里,要用的时候,直接拿出来,在前面加上MM的名字就可以发送了,再不用一个字一个字敲了。共享的句子就是Flyweight,MM的名字就是提取出来的外部特征,根据上下文情况使用。
        享元模式:FLYWEIGHT在拳击比赛中指最轻量级。享元模式以共享的方式高效的支持大量的细粒度对象。说的再具体一些是将所有具有相同状态的对象指向同一个引用,从而解决了系统在创建大量对象时所带来的内存压力。
        享元模式能做到共享的关键是区分内蕴状态和外蕴状态。

        内蕴状态存储在享元内部并且可以共享,不会随环境的改变而有所不同。
外蕴状态是随环境的改变而改变的,不可以共享。外蕴状态不能影响内蕴状态,它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。
        亨元对象的外蕴状态必须由客户端保存,并在亨元对象被创建之后,在需要使用的时候再传入到亨元对象内部。

注意:客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。

(C++设计模式) ------享元模式-- 结构型模式_第1张图片

 使用的场合:

  • 需要创建大量对象。
  • 考虑内存成本。
  • 大多数对象属性可以对外共享。
  • 应用程序不必授权给唯一的对象,因为同一对象被实例后需要被重复使用。

    例子:

    比如围棋有300颗棋子,用一般的设计模式,创建一个类,每个棋子都用一个对象的话那就会非常麻烦,并且各自定义各自在棋盘的位置.....等等
    而使用亨元模式来实现的话,就用两个对象 :一个黑,一个白。
    这样就可以了,至于棋子的方位不同,那只是对象的不同的外部表现形式或者说是外部状态。
    这样三百多个对象就减到了两个对象。
    优缺点:

    优点:减少对象数量,节省内存空间
    缺点:维护共享对象,需要额外开销

    换句话说就是:享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的:享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。另外它将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

    本质:

    分离与共享

  •  

    代码举例:引用自:http://blog.csdn.net/roynee/article/details/4633474

  • 以纯文本为例,每个字符CharFlyweight为共享的轻量级对象,而由这些字符构成的行则为非共享的对象RowFlyweight,而TextFlyweightFactory则管理其共享对象的对象池。当用户向该工厂请求字符时,就从对象池中取得,而当用户向该工厂请求字符串时候则通过创建非共享的RowFlyweight获取,但此种每个字符的获取仍然向TextFlyweightFactory共享对象的对象池提出请求。

    (C++设计模式) ------享元模式-- 结构型模式_第2张图片

     

  • 【程序】

      // test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "iostream" #include "string" #include <vector> using namespace std; /** * AbstractFlyweight Class[Abstract Class] */ class AbstractFlyweight { public: AbstractFlyweight(){} virtual ~AbstractFlyweight(){} /// Interface of Writing the Element of Flyweight virtual void Write()=0; }; class CharFlyweight:public AbstractFlyweight { public: /*constructor and destructor*/ CharFlyweight(char tChar) { this->_Char=tChar; } virtual ~CharFlyweight(){} /// Interface of Writing the Element of Flyweight virtual void Write() { cout<<this->_Char<<flush; return; } /// Get the Char virtual char GetChar() { return this->_Char; } private: char _Char; }; class RowFlyweight:public AbstractFlyweight { public: RowFlyweight(){} virtual ~RowFlyweight(){} /// Interface of Writing the Element of Flyweight virtual void Write() { for(vector<abstractflyweight>::iterator iter=this->_vecFlyweight.begin();iter!=this->_vecFlyweight.end();++iter) (*iter)->Write(); return; } virtual void AddFlyweight(AbstractFlyweight * flyweight) { this->_vecFlyweight.push_back(flyweight); } private: vector<abstractflyweight> _vecFlyweight; }; /** * TextFlyweightFactory: provide the CharFlyweight object */ class TextFlyweightFactory { public: /*Constructor and destructor*/ TextFlyweightFactory(){} virtual ~TextFlyweightFactory(){} /// Get the CharFlyweight Object virtual AbstractFlyweight* GetFlyweight(char _char) { vector<charflyweight>::iterator iter = this->_vecCharFlyweight.begin(); for(;iter != this->_vecCharFlyweight.end();++iter) { if((*iter)->GetChar()==_char)return *iter; } CharFlyweight *newchar=new CharFlyweight(_char);/*new character*/ this->_vecCharFlyweight.push_back(newchar); /*Record it*/ return newchar; } virtual AbstractFlyweight* GetFlyweight(string str) { RowFlyweight *row=new RowFlyweight(); for(int i=0;i < str.length();++i) row->AddFlyweight(this->GetFlyweight(str[i])); /*Get the char from VecCharFlyweight*/ return row; } /// Just be used to show the size of vector virtual int SizeVector() { return this->_vecCharFlyweight.size(); } private: /*CharFlyweight Vector*/ vector<charflyweight> _vecCharFlyweight; }; int main (int argc, char *argv[]) { /*Now There is A factory*/ TextFlyweightFactory *factoryApi=new TextFlyweightFactory(); /*Now Get CharFlyweight-shared*/ factoryApi->GetFlyweight('a')->Write(); factoryApi->GetFlyweight('a')->Write(); factoryApi->GetFlyweight('c')->Write(); cout<<"\nFactory's Size is: "<<factoryapi->SizeVector(); /*Now New a Row-unshared*/ factoryApi->GetFlyweight("hello \n")->Write(); return(0); } </factoryapi-></this->

  • 运行结果:

  • (C++设计模式) ------享元模式-- 结构型模式_第3张图片

  •  

      virtual AbstractFlyweight* GetFlyweight(string str) 
        { 
            RowFlyweight *row=new RowFlyweight(); 
            for(int i=0;i < str.length() -1;++i)     //这地方改成减一
                row->AddFlyweight(this->GetFlyweight(str[i]));  /*Get the char from VecCharFlyweight*/ 
            return row; 
        } 
  •  然后main函数修改一下更能体现共享的概念: virtual AbstractFlyweight* GetFlyweight(string str) { RowFlyweight *row=new RowFlyweight(); for(int i=0;i < str.length() -1;++i) //这地方改成减一 row->AddFlyweight(this->GetFlyweight(str[i])); /*Get the char from VecCharFlyweight*/ return row; } int main (int argc, char *argv[]) { /*Now There is A factory*/ TextFlyweightFactory *factoryApi=new TextFlyweightFactory(); /*Now Get CharFlyweight-shared*/ factoryApi->GetFlyweight('a')->Write(); factoryApi->GetFlyweight('a')->Write(); factoryApi->GetFlyweight('a')->Write(); cout<<"\nFactory's Size is: "<<factoryapi->SizeVector(); /*Now New a Row-unshared*/ factoryApi->GetFlyweight("aaaaaaa\n")->Write(); cout<<"\nFactory's Size is: "<<factoryapi->SizeVector()<<endl; return(0); } </factoryapi-></factoryapi->
  • 输出结果是:
  • (C++设计模式) ------享元模式-- 结构型模式_第4张图片
  • 不错的相关网站:①http://www.csdn.net/article/2012-06-25/2806857

  • ② http://blog.csdn.net/roynee/article/details/4633474

  • 你可能感兴趣的:((C++设计模式) ------享元模式-- 结构型模式)