zoukankan      html  css  js  c++  java
  • 【设计模式】——享元模式

    享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象。

     

    #include <iostream>
    #include <vector>
    using namespace std;
    //Flyweight类,它是所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态
    class Flyweight
    {
    public:
        virtual void Operator(int extrinsicstate)=0;
    };
    //ConcreteFlyweight是继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间
    class ConcreteFlyweight:public Flyweight
    {
    public:
        void Operator(int extrinsicstate)
        {
            cout << "具体Flyweight:" << extrinsicstate << endl;
        }
    };
    //UnsharedConcreteFlyweight是指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但他并不强制共享
    class UnsharedConcreteFlyweight:public Flyweight
    {
    public:
        void Operator(int extrinsicstate)
        {
            cout << "不共享的具体Flyweight:" << extrinsicstate << endl;
        }
    };
    //FlyweightFactory,是一个享元工厂,用来创建并管理Flyweight对象。它主要是用来确保合理的共享Flyweight,
    //当用于请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)
    class FlyweightFactory
    {
    private:
        vector<Flyweight*> m_flyweights;
    public:
        FlyweightFactory()
        {
            Flyweight *temp=new ConcreteFlyweight();
            m_flyweights.push_back(temp);
        }
        Flyweight *GetFlyweight(int key)
        {
            return m_flyweights.at(key);
        }
    };
    int main()
    {
        int exetrinsicstate=22;
        FlyweightFactory *f=new FlyweightFactory();
        Flyweight *fx=f->GetFlyweight(0);
        fx->Operator(exetrinsicstate);
        return 0;
    }

      在享元对象内部并且不会随环境改变而改变的共享部分,可以成为是享元对象的内部状态,而随环境改变而改变的、不可以共享的状态就是外部状态了。事实上,享元模式可以避免大量非常相似的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是相同的,有时就能够受大幅度地减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。也就是说,享元模式Flyweight执行时所需的状态是有内部的也可能有外部的,内部状态存储于ConcreteFlyweight对象之中,而外部对象则应该考虑由客户端对象存储或计算,当调用Flyweight对象的操作时,将该状态传递给它。

    下面是关于网站分类的例子:

     

    #include <iostream>
    #include <map>
    using namespace std;
    //用户类,用于网站的客户帐号,是“网站”类的外部状态
    class User
    {
    private:
        string m_name;
    public:
        User(string name)
        {
            this->m_name=name;
        }
        string GetName()
        {
            return m_name;
        }
    };
    //网站抽象类
    class WebSite
    {
    public:
        virtual void Use(User *user){}
    };
    //具体网站类
    class ConcreteWebSite:public WebSite
    {
    private:
        string m_name;
    public:
        ConcreteWebSite(string name)
        {
            this->m_name=name;
        }
        void Use(User *user)
        {
            cout << "网站分类:" << m_name << " 用户:" << user->GetName()<< endl;
        }
    };
    //网站工厂类
    class WebSiteFactory
    {
    private:
        map<string,WebSite*> m_flyweights;
    public:
        //获得网站分类
        WebSite *GetWebSiteCategory(string key)
        {
            if(m_flyweights.find(key)==m_flyweights.end())
                m_flyweights[key]=new ConcreteWebSite(key);
            return m_flyweights[key];
        }
    };
    int main()
    {
        WebSiteFactory *f=new WebSiteFactory();
        WebSite *fx=f->GetWebSiteCategory("产品展示");
        fx->Use(new User("小菜"));
        WebSite *fy=f->GetWebSiteCategory("产品展示");
        fy->Use(new User("大鸟"));
        WebSite *f1=f->GetWebSiteCategory("博客");
        f1->Use(new User("老顽童"));
        WebSite *fm=f->GetWebSiteCategory("博客");
        fm->Use(new User("Awy"));
        return 0;
    }

      如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时,就应该考虑使用;还有就是对象的大多数状态可以是外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。因为用了享元模式,所以有了共享对象,实例总数就大大减少了,如果共享的对象越多,存储节约也就越多,节约量随着共享状态的增多而增大。

      在某些情况下,对象的数量可能会太多,从而导致了运行时的资源与性能损耗。那么我们如何去避免大量细粒度的对象,同时又不影响客户程序,是一个值得去思考的问题,享元模式,可以运用共享技术有效地支持大量细粒度的对象。不过,你也别高兴得太早,使用享元模式需要维护一个记录了系统已有的所有享元的列表,而这本身需要耗费资源,另外享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,使得程序的逻辑发扎花。因此,应当在有足够多的对象实例可供共享时才值得使用享元模式。

  • 相关阅读:
    zpf 视图
    html5本地存储
    sqlite 使用记录
    百度开放平台
    PHP exit() 输出
    yum笔记
    手动编译安装软件
    while循环
    linux下面测试网络带宽 (转载)
    软件包管理器的核心功能(笔记)
  • 原文地址:https://www.cnblogs.com/awy-blog/p/3844027.html
Copyright © 2011-2022 走看看