新版MQL语言程序设计:享元模式的原理、应用及代码实现

一、什么是享元模式

享元模式是一种结构型设计模式,它通过共享对象来减少内存使用和提高性能。在享元模式中,对象被分为两种类型:内部状态和外部状态。内部状态是可以共享的,而外部状态是不可共享的。

二、享元模式的实现原理

  1. 创建一个抽象享元类,定义了具体享元类需要实现的方法。
  2. 创建具体享元类,实现抽象享元类定义的方法,并定义内部状态和外部状态。
  3. 创建一个享元工厂类,用于管理和创建享元对象。该工厂类维护一个享元池,用于存储已经创建的享元对象。
  4. 在客户端中,通过享元工厂类获取或创建享元对象,并将外部状态传递给享元对象。

注意:通过使用享元模式,可以有效地减少对象的数量,提高系统的性能和内存利用率。但需要注意的是,享元模式适用于对象的内部状态较多且相似的情况,如果对象的内部状态较少或者差异较大,则可能无法获得明显的性能提升。

三、享元模式的应用场景

1.绘图工具的应用。

在绘图工具中,用户可以选择不同的形状(如圆形、矩形、三角形等)进行绘制。如果每次用户选择一个形状时都创建一个新的对象,那么会消耗大量的内存。而使用享元模式,可以共享相同形状的对象,只需存储一份形状的状态信息,并在需要时进行复用。

举个例子,假设用户在绘图工具中选择了一个红色的圆形进行绘制。当用户再次选择红色圆形时,可以直接使用之前创建的对象,而不需要再次创建一个新的对象。这样可以减少内存使用,并提高性能。

2.文本编辑器中的字符对象的应用。

在文本编辑器中,每个字符都可以看作是一个对象。如果每个字符都创建一个新的对象,那么对于大文本文件来说,将会消耗大量的内存。而使用享元模式,可以共享相同字符的对象,只需存储一份字符的状态信息,并在需要时进行复用。

3. 量化交易系统的设计

在量化交易系统中,可能存在大量的交易策略对象,这些对象可能具有相同的属性和行为,只是在具体的参数上有所不同。如果每个策略对象都独立创建,会占用大量的内存资源。而使用享元模式,可以将相同的属性和行为抽象出来,作为共享的部分,而将不同的参数作为外部状态,在需要时动态传入。

具体应用方面,享元模式可以在以下几个方面发挥作用:

交易策略对象的共享:将相同的交易策略对象共享,减少内存占用。例如,如果有多个策略对象使用相同的技术指标计算方法,可以将这部分计算方法抽象出来作为共享的部分。

缓存数据对象:在量化交易系统中,可能需要频繁地获取历史数据、实时行情等信息。使用享元模式可以将这些数据对象缓存起来,避免重复创建和销毁,提高系统性能。

共享工具类:在量化交易系统中,可能存在一些通用的工具类,例如日期处理、数学计算等。这些工具类可以使用享元模式进行共享,避免重复创建和加载,提高系统效率。

总之,享元模式在量化交易系统中的应用可以减少内存占用、提高系统性能,并且可以通过共享对象来优化系统设计。

四、享元模式的代码实现

//+------------------------------------------------------------------+
//| structure                                                        |
//+------------------------------------------------------------------+
//
//      |      FlyweightFactory     |o------------------>*|         Flyweight        |
//      |---------------------------|                     |--------------------------|
//   +->|GetFlyweight(key)          |                     |Operation(extrinsic_state)|
//   |  | if(flyweight[key] exists) |                                   ^
//   |  |  return existing flyweight|                                   |
//   |  | else                      |                   +---------------+----------------+
//   |  |  create new flyweight     |                   |                                |
//   |  |  add it to the pool of    |   +->|     ConcreteFlyweight    |   +->|UnsharedConcreteFlyweight |
//   |  |   flyweights              |   |  |--------------------------|   |  |--------------------------|
//   |  |  return the new flyweight |   |  |Operation(extrinsic_state)|   |  |Operation(extrinsic_state)|
//   |                                  |  |--------------------------|   |  |--------------------------|
//   |                                  |  |intrinsic_state           |   |  |all_state                 |
//   |                                  |                                 |
//|Client|------------------------------+---------------------------------+
//
//+------------------------------------------------------------------+
//| diagram — sharing of flyweights                                  |
//+------------------------------------------------------------------+
//
//                                      |aClient|              |aClient|
//                                      |-------|              |-------|
//                                      |   *   |  +-----------|-* *   |
//                                          |      |               |
//                             +------------|------|---------------|--------------+
//                             |flyweights  |      |               |              |
//                             |pool        |      |               |              |
//                             |            v      v               v              |
//|aFlyweightFactory|          |   |ConcreteFlyweight|      |ConcreteFlyweight|   |
//|-----------------|          |   |-----------------|      |-----------------|   |
//|flyweights   *---|----+-----|-->|intrinsic_state  |   +->|intrinsic_state  |   |
//                       |     |                         |                        |
//                       +-----|-------------------------+                        |
//                             +--------------------------------------------------+
//
//+------------------------------------------------------------------+
//| interface — for patterns                                         |
//+------------------------------------------------------------------+
interface ClientInterface
{
   
    string Output(void);
    void Run(void);
};
//+------------------------------------------------------------------+
//| interface — for patterns                                         |
//+------------------------------------------------------------------+
void Run(ClientInterface* client) 
{
   
    printf("---\n%s",client.Output());
    client.Run();
    delete client;
}
// 声明了一个接口,蝇量级可以通过该接口接收
// 并根据外在状态行事
interface Flyweight
{
   
    void Operation(int extrinsic_state);
};
//+------------------------------------------------------------------+
//| class — flyweight pair                                           |
//+------------------------------------------------------------------+
class Pair
{
   
    protected:
        string            key;
        Flyweight*        value;
    public:
        Pair(void);
        Pair(string, Flyweight*);
        ~Pair(void);
        Flyweight*        Value(void);
        string            Key(void);
};
//+------------------------------------------------------------------+
//| flyweight pair > constructor > default                           |
//+------------------------------------------------------------------+
Pair::Pair(void)
{
   

}
//+------------------------------------------------------------------+
//| flyweight pair > constructor > key — value                       |
//+------------------------------------------------------------------+
Pair::Pair(string a_key,Flyweight *a_value):
    key(a_key),
    value(a_value)
{
   
}
//+------------------------------------------------------------------+
//| flyweight pair > destructor                                      |
//+------------------------------------------------------------------+
Pair::~Pair(void)
{
   
    delete value;
}
//+------------------------------------------------------------------+
//| flyweight pair > get — key                                       |
//+------------------------------------------------------------------+
string Pair::Key(void)
{
   
    return key;
}
//+------------------------------------------------------------------+
//| flyweight pair > get — value                                     |
//+------------------------------------------------------------------+
Flyweight* Pair::Value(void)
{
   
    return value;
}
//+------------------------------------------------------------------+
//| class — flyweight dictionary                                     |
//+------------------------------------------------------------------+
class Dictionary
{
   
    protected:
        Pair*             pairs[];
    public:
        Dictionary(void);
        ~Dictionary(void);
        void              Add(string,Flyweight*);
        bool              Has(string);
        Flyweight*        operator[](string);
    protected:
        int               Find(string);
};
//+------------------------------------------------------------------+
//| flyweight dictionary > constructor                               |
//+------------------------------------------------------------------+
Dictionary::Dictionary(void)
{
   
}
//+------------------------------------------------------------------+
//| flyweight dictionary > destructor                                |
//+------------------------------------------------------------------+
Dictionary::~Dictionary(void)
{
   
    int total=ArraySize(pairs);
    for(int i=0; i<total; i++)
    {
   
        Pair* ipair=pairs[i];
        if(CheckPointer(ipair))
        {
   
            delete ipair;
        }
    }
}
//+------------------------------------------------------------------+
//| flyweight dictionary > find key                                  |
//+------------------------------------------------------------------+
int Dictionary::Find(string key)
{
   
    int total=ArraySize(pairs);
    for(int i=0; i<total; i++)
    {
   
        Pair* ipair=pairs[i];
        if(ipair.Key()==key)
        {
   
            return i;
        }
    }
    return -1;
}
//+------------------------------------------------------------------+
//| flyweight dictionary > has key                                   |
//+------------------------------------------------------------------+
bool Dictionary::Has(string key)
{
   
    return (Find(key)>-1)?true:false;
}
//+------------------------------------------------------------------+
//| flyweight dictionary > add key — value                           |
//+------------------------------------------------------------------+
void Dictionary::Add(string key,Flyweight *value)
{
   
    int size=ArraySize(pairs);
    ArrayResize(pairs,size+1);
    pairs[size]=new Pair(key,value);
}
//+------------------------------------------------------------------+
//| flyweight dictionary > get value at key                          |
//+------------------------------------------------------------------+
Flyweight* Dictionary::operator[](string key)
{
   
    int find=Find(key);
    return (find>-1)?pairs[find].Value():NULL;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| participants > concrete flyweight                                |
//+------------------------------------------------------------------+
class ConcreteFlyweight:public Flyweight
{
   
    public:
        void              Operation(int extrinsic_state);
    protected:
        int               intrinsic_state;
};
//+------------------------------------------------------------------+
//| participants > concrete flyweight > operation                    |
//+------------------------------------------------------------------+
void ConcreteFlyweight::Operation(int extrinsic_state)
{
   
    intrinsic_state=extrinsic_state;
    printf("intrinsic state: %d",intrinsic_state);
}
//+------------------------------------------------------------------+
//| participants > unshared concrete flyweight                       |
//+------------------------------------------------------------------+
class UnsharedConcreteFlyweight:public Flyweight
{
   
    protected:
        int               all_state;
    public:
        void              Operation(int extrinsic_state);
};
//+------------------------------------------------------------------+
//| participants > unshared concrete flyweight > operation           |
//+------------------------------------------------------------------+
void UnsharedConcreteFlyweight::Operation(int extrinsic_state)
{
   
    all_state=extrinsic_state;
    printf("all state: %d",all_state);
}
//+------------------------------------------------------------------+
//| participants > flyweight factory                                 |
//+------------------------------------------------------------------+
class FlyweightFactory
{
   
    protected:
        Dictionary        pool;
    public:
        FlyweightFactory(void);
        Flyweight*        Flyweight(string key);
};
//+------------------------------------------------------------------+
//| participants > flyweight factory > constructor                   |
//+------------------------------------------------------------------+
FlyweightFactory::FlyweightFactory(void)
{
   
    pool.Add("1",new ConcreteFlyweight);
    pool.Add("2",new ConcreteFlyweight);
    pool.Add("3",new ConcreteFlyweight);
}
//+------------------------------------------------------------------+
//| participants > flyweight factory > get flyweight                 |
//+------------------------------------------------------------------+
Flyweight* FlyweightFactory::Flyweight(string key)
{
   
    if(!pool.Has(key)) //pool has no such key
    {
   
        pool.Add(key,new ConcreteFlyweight()); //create new key—flyweight pair
    }
    return pool[key]; //return flyweight at key
}
//+------------------------------------------------------------------+
//| participants > client                                            |
//+------------------------------------------------------------------+
class Client:public ClientInterface
             //   maintains a reference to flyweight(s)
             //   computes or stores the extrinsic state of flyweight(s)
{
   
    public:
        string            Output();
        void              Run();
};
string Client::Output(void)
{
   
    return __FUNCTION__;
}
//+------------------------------------------------------------------+
//| collaborations                                                   |
//+------------------------------------------------------------------+
void Client::Run(void)
{
   
    int extrinsic_state=7;
    Flyweight* flyweight;
    FlyweightFactory factory;
    //---the extrinsic state is relayed to all flyweights
    flyweight=factory.Flyweight("1");
    flyweight.Operation(extrinsic_state);
    flyweight=factory.Flyweight("10");
    flyweight.Operation(extrinsic_state);
    //---
    flyweight=new UnsharedConcreteFlyweight();
    flyweight.Operation(extrinsic_state);
    delete flyweight;
}
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   
    //---structural
    Run(new Client);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| output                                                           |
//+------------------------------------------------------------------+
//   Flyweight::Client::Output
//   intrinsic state: 7
//   intrinsic state: 7
//   all state: 7

最近更新

  1. TCP协议是安全的吗?

    2024-02-07 06:24:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-07 06:24:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-07 06:24:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-07 06:24:03       20 阅读

热门阅读

  1. 使用lodash防抖节流

    2024-02-07 06:24:03       29 阅读
  2. Spark scala如何本地运行

    2024-02-07 06:24:03       29 阅读
  3. leetcode - 408. Valid Word Abbreviation

    2024-02-07 06:24:03       26 阅读
  4. Docker- chapter 1

    2024-02-07 06:24:03       26 阅读
  5. 谈谈mybatis的理解(一)

    2024-02-07 06:24:03       28 阅读
  6. 小程序API开发——文件FileSystemManager参数汇总

    2024-02-07 06:24:03       28 阅读
  7. 深度解析与推荐:主流Web前端开发框架

    2024-02-07 06:24:03       28 阅读
  8. Lua函数进阶

    2024-02-07 06:24:03       38 阅读
  9. LCP 30. 魔塔游戏---leetcode

    2024-02-07 06:24:03       32 阅读
  10. 嵌入式linux驱动开发之网络设备驱动

    2024-02-07 06:24:03       26 阅读
  11. 前端下载文件有哪些方式

    2024-02-07 06:24:03       31 阅读
  12. day12笔记(学生管理系统升级版)

    2024-02-07 06:24:03       28 阅读