《大话设计模式》-- 第26个 享元模式

享元模式目的是为了减少对象实例化的个数,已达到减少对象占用内存的目的。他创建对象是通过工厂创建的,在工厂类中创建对象时,会先判断此对象是否已经存在,如果不存在则创建对象,如果存在则返回已经存在的对象,这是享元模式的核心部分。对于对象间的不同部分,则采用参数传递的方式将不同部分传进类的处理函数。
代码如下:

#include 
#include 
#include 
using namespace std;

class FlyWeight
{
public:
    FlyWeight() {}
    virtual void Operation (int extrinsicstate) = 0;
};

class ConcreteFlyWeight : public FlyWeight
{
public:
    void Operation (int extrinsicstate)
    {   
        cout << "ConcreteFlyWeight: " << extrinsicstate << endl;
    }
};

class UnsharedConcreteFlyWeight :public FlyWeight
{
public:
    void Operation (int extri)
    {   
        cout << "UnsharedConcreteFlyWeight: " << extri << endl;
    }
};

class FlyWeightFactory
{
public:
    FlyWeightFactory ()
    {
        FlyWeight *f1 = new ConcreteFlyWeight ;
        FlyWeight *f3 = new ConcreteFlyWeight ;
        FlyWeight *f2 = new ConcreteFlyWeight ;
        flyweights.insert (make_pair ("han", f1));
        flyweights.insert (make_pair ("wang", f2));
        flyweights.insert (make_pair ("zhang", f3));
    }
    FlyWeight* GetFlyWeight (string key)
    {   
        return flyweights[key];
    }
private:
    map <string, FlyWeight *> flyweights;
};
class User
{
public:
    User (string nm) : name (nm) {}
    string GetName () { return name; }
private:
    string name;
};

class WebSite
{
public:
    virtual void Use (User *user) = 0;
};

class ConcreteWebSite : public WebSite
{
public:
    ConcreteWebSite (string nm) : name (nm) {}
    void Use (User *user)
    {
        cout << "ConcreteWebSite: " << name << "User: " << user->GetName()<< endl;
    }
private:
    string name;
};

class WebSiteFactory
{
public:
    WebSite* GetWebSiteCategory (string key)
    {
        if (websites.find(key) == websites.end())
            websites.insert(make_pair(key, new ConcreteWebSite(key)));
        return websites[key];
    }
    int GetWebSiteCount ()
    {
        return websites.size();
    }
private:
    map <string, WebSite*> websites;
};
int main(void)
{
    int extrinsicstate = 22;
    FlyWeightFactory *f = new FlyWeightFactory ();
    FlyWeight *fx = f->GetFlyWeight ("han");
    fx->Operation (--extrinsicstate);
    FlyWeight *fy = f->GetFlyWeight ("wang");
    fy->Operation (--extrinsicstate);
    FlyWeight *fz = f->GetFlyWeight ("zhang");
    fz->Operation (--extrinsicstate);

    UnsharedConcreteFlyWeight *uf = new UnsharedConcreteFlyWeight ();
    uf->Operation (--extrinsicstate);
    cout << "-----------------------" << endl;

    WebSiteFactory *fw = new WebSiteFactory;
    WebSite *fwn = fw->GetWebSiteCategory ("novel");
    fwn->Use(new User ("hb"));
    WebSite *fwb = fw->GetWebSiteCategory ("bolg");
    fwb->Use(new User ("zt"));
    cout << fwn << " " << fwb << endl;

    WebSite *fwn2 = fw->GetWebSiteCategory ("novel");
    cout << fwn2 << endl;
    cout << fw->GetWebSiteCount () << endl;

    char *p1 = "world";
    char *p2 = "world";
    cout << (const void*)p1 << " " << (const void*)p2 << endl;
    return 0;
}

运行结果如下:

ConcreteFlyWeight: 21
ConcreteFlyWeight: 20
ConcreteFlyWeight: 19
UnsharedConcreteFlyWeight: 18
-----------------------
ConcreteWebSite: novelUser: hb
ConcreteWebSite: bolgUser: zt
0x9ff8f28 0x9ff8f98
0x9ff8f28
2
0x804c6d6 0x804c6d6

实现享元模式的核心在WebSiteFactory类,此类是一个对象工厂生成类,在生成一个对象时,它回去已经存在的对象集合websites中查找,若找到了则直接返回,若没有找到则new一个新对象并返回。

希望以后可以遇到用享元模式的场景,碰见别人写的代码运用此模式的也能够识别出来。

ps:代码最后两个相同的字符串char *p1 = "world";
char *p2 = "world";
打印出两个字符串的地址发现地址是一样的,这也是享元模式的一个应用。

你可能感兴趣的:(设计模式,设计模式)