zoukankan      html  css  js  c++  java
  • 享元模式及C++实现

    享元模式(flyweight)

    flyweight是轻量级的意思,中文这边翻译成享元,更容易让人理解一些。

    享元模式是为了应对大量细粒度对象重复的问题。程序中存在大量细粒度的对象,每次要使用时都必须创建一个新的对象,既影响了运行效率又增加了内存消耗。于是有了享元模式,享元模式提取出这些细粒度对象中间公共的状态(属性,我的理解),只生成一个实例对象,所有用到这些公共属性对象的地方,都指向这一个实例。

    根据我的理解,很多类有一部分的属性是可以共享的,而不可共享的部分需要提取出来,通过参数传递来使用。

    典型的享元模式的例子为文书处理器中以图形结构来表示字符。一个做法是,每个字形有其字型外观,字模metrics,和其他格式资讯,但为每个字符都生成这些书写,就会额外消耗许多的内存空间。取而代之的是,每个字符参照一个共享字形物件,此物件会被其他有共同特质的字符所分享;只有每个字符的位置才需要另外存储。[摘自 维基百科-享元模式]

    文书处理器是最普遍的用来说明享元模式的例子。从这个例子就能看到哪些是可以被共享的,哪些是不能被共享的,通过这种方式达到提高系统效率和减小内存消耗的目的。

    从下图看出,ConcreteFlyWeight就是可以共享的部分,通过工厂模式的方式来选择共享的实例,客户端就可以直接使用了。

    我感觉就有点像简单工厂模式,区别是不像工厂模式一样每次都生成一个不同的对象实例,而是返回一个现成的对象实例。

    暂时就只理解了这么多,其他的需要在实践中慢慢的总结。

    image

    常用场景

    1.当系统中有大量的细粒度对象实例,而且这些对象实例中有一些属性是重复的情况下,考虑使用。

    文本编辑器,输入法之类的常用应用。

     

    优点

    1.提高了系统的效率,减小了内存的消耗。

    2.减少了重复代码。

    3.减少了系统的复杂度。

    缺点

    1.维护共享对象和查找所需的共享对象需要花费很多时间。

    C++实现

     1 #ifndef _FLYWEIGHT_H_
     2 #define _FLYWEIGHT_H_
     3 
     4 
     5 class FlyWeight
     6 {
     7 public:
     8     FlyWeight(){};
     9     virtual ~FlyWeight(){};
    10 
    11     virtual void operation() = 0;
    12 
    13 };
    14 
    15 
    16 class ConcreteFlyWeight: public FlyWeight
    17 {
    18 public:
    19     ConcreteFlyWeight(){};
    20     ~ConcreteFlyWeight(){};
    21     
    22     void operation();
    23     
    24 };
    25 
    26 
    27 
    28 #endif
    FlyWeight.h
    1 #include "FlyWeight.h"
    2 #include <stdio.h>
    3 
    4 
    5 void ConcreteFlyWeight::operation()
    6 {
    7     printf("I'm ConcreteFlyWeight!
    ");
    8 }
    FlyWeight.cpp
     1 #ifndef _FLYWEIGHT_FACTORY_H_
     2 #define _FLYWEIGHT_FACTORY_H_
     3 
     4 #include <vector>
     5 #include "FlyWeight.h"
     6 
     7 using namespace std;
     8 
     9 class FlyWeightFactory
    10 {
    11   public:
    12     FlyWeightFactory();
    13     ~FlyWeightFactory();
    14 
    15     FlyWeight* GetFlyWeight(int key);
    16 
    17   private:
    18     vector<FlyWeight*> m_flyWeights;//很多时候为了增加效率,使用hash表之类的结构,这里简单的使用vector
    19 };
    20 
    21 #endif
    FlyWeightFactory.h
     1 #include "FlyWeightFactory.h"
     2 
     3 FlyWeightFactory::FlyWeightFactory()
     4 {
     5     FlyWeight* tmp = new ConcreteFlyWeight();
     6     m_flyWeights.push_back(tmp);
     7 }
     8 
     9 
    10 
    11 
    12 FlyWeightFactory::~FlyWeightFactory()
    13 {
    14     FlyWeight* tmp = m_flyWeights.at(0);
    15     delete tmp;
    16     tmp = NULL;
    17 }
    18 
    19 
    20 
    21 
    22 FlyWeight* FlyWeightFactory::GetFlyWeight(int key)
    23 {
    24     //简单点表示
    25     return m_flyWeights.at(key);
    26 }
    FlyWeightFactory.cpp
     1 #include "FlyWeightFactory.h"
     2 
     3 
     4 
     5 int main()
     6 {
     7     FlyWeightFactory* factory = new FlyWeightFactory();
     8 
     9     FlyWeight* flyWeight = factory->GetFlyWeight(0);
    10     flyWeight->operation();
    11     return 0;
    12 }
    client.cpp
    g++ -o client client.cpp FlyWeight.cpp FlyWeightFactory.cpp

    运行结果

    image

  • 相关阅读:
    修改FileUpload样式
    ASP.NET 中JSON 的序列化和反序列化
    C# 2.0中泛型编程初级入门
    50条经典爱情观
    (转贴)追MM与Java的23种设计模式
    猴子和香蕉的故事
    35岁前成功的12条黄金法则
    几个小故事
    java与C++的虚函数比较
    flask 源码解析:上下文(一) SUNNEVER
  • 原文地址:https://www.cnblogs.com/cxjchen/p/3194379.html
Copyright © 2011-2022 走看看