模型

模型

动机

  1.    规范市场模型和结构,为市场的交互者提供标准的行为模式;
  2.    提供符合规范的最简易实现;
  3.    实现数据和算法分离;
  4.    实现数据的可配置,以及数据结构的可替换;
  5.    实现算法的可替换;
  6.    提供灵活的扩展性,并对扩展过程进行规范;
  7.    充分利用Spring容器的特性,在面向Spring3的同时为Spring2.x提供兼容包装层;
  8.    实现数据和算法分离;

行动

  1. 命名对象

          市场中的对象是可以识别的,而且通常是通过名字识别,称这些对象为命名对象:

    1        public interface NamedObject {
    2            String getName();
    3            void setName(String name);
    4        }
    5    

          有些对象是通过Identity或者Code之类的属性唯一识别。为了编程方便,称这个Identity和Code就是Name,因此这里的name是一个广义上的含义,表示可以唯一识别。

          图表1中的市场、各类管理器以及被它们管理的对象都是命名对象。

  2. 市场对象和市场对象管理器

    1    public interface Managable<T extends Managable<T>> extends NamedObject {
    2        public ManagerOf<T, ? extends MarketModel> getManager();
    3        public void setManager(ManagerOf<T, ? extends MarketModel> manager);
    4    }
    5    

          市场中的对象和对象管理器有着管理和被管理的关系,一个特定类型管理器管理着一个或多个这种类型的对象。因此市场对象和市场对象管理器有着以下的特征:

    1    public interface Managable<T extends Managable<T>> extends NamedObject {
    2        public ManagerOf<T, ? extends MarketModel> getManager();
    3        public void setManager(ManagerOf<T, ? extends MarketModel> manager);
    4    }
    5    

          模块为所有的管理器提供了基本的必要支持:CommonMarketManagedObject和 MarketObjectManager,市场对象继承CommonMarketManagedObject,而市场对象管理器则继承MarketObjectManager即可。

  3. 加权

          在市场的模型中,使用以系列的加权来观察和设置市场。当前使用的加权有维度有货种,航线和时间。其中时间的加权自变量是连续的,而货种和航线的加权自变量是离散的。在业务中,决定了加权维度货种和航线是正交的(平行的),而时间维度是嵌套的。在实际使用中,正交加权系和当成嵌套加权系处理,反之则不行。所以,在当前的市场模型下,

     1    public interface Weight{
     2        String getName();
     3        WeightSeries getWeightSeries();
     4        double getValue();
     5    }
     6
     7    public interface WeightSeries {
     8        // 加权系列的名称
     9        String getName();
    10
    11        // 加权系列的加权表
    12        List<Weight> getWeights()
    13
    14        // 获取指定名称加权点的子加权系列,如果加权点不存在,返回null
    15        WeightSeries getChildSeries(String weightName);
    16
    17        // 求取指定加权所占的百分比,如果加权不存在,返回0.0%
    18        double getPercent( String weightName);
    19
    20        // 求取加权路径上的百分比;加权路径,排在前面的先加权;如果加权路径不正确,返回0.0%
    21        double getPercent(List<String> weightNames);
    22    }
    23    

          加权系应该是货物种类 > 航线 > 时间,或者是 航线 > 货物种类 > 时间。

  4. 市场时钟

      市场是随时间变化而变化的。在同一个时刻,市场的状态是相同的,只能有一种。因此在这个角度,可以认为市场的原始驱动力量是时间。考虑到系统的使用方式,模拟市场中的终具有现实客观始终以外的其他附加属性:1) 可操控性:停止、启动;2) 可跳跃性:不连续现实客观时间也可以在这个时钟上表示为连续的。

      为了符合上述要求,市场时钟额外提供了一个时间记录器。为了使关于市场时钟时间的编程规范统一,模块定义了接口ClockWatcher,并提供了其管理接口和缺省的实现。

      市场时钟部分相关的程序结构如下图所示:

模型

【注意事项】对于耗时较多的ClockWatcher实现,应实现为独立的线程,或者实现一个缺省启动新的工作线程的ClockWatcherManager。