快速业务通道

按照类型名称动态创建对象

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29
法通过编译的。可以通过修改接口的设计来避开这个问题,即增加默认构造函数和指定端口的构造函数。虽然这和实际情况不符(因为这里的设备不支持热插拔,不能再程序运行时更换连接的端口),但是为了便于实现也是可以接受的。

但是,更隐蔽的一个缺陷是,如果设备类本身的尺寸较大,那么为所有支持的型号创建实例,将增加空间负荷,而实际上实际使用的设备可能仅仅只用到其中的两三个型号而已。

从这个角度看,型号映射表中应该映射的是类的创建器,而不是类的实例本身,而类的创建器几乎没有什么空间负担。

这里有一个极其简单的创建器,

template <class T>
   IntelligentMotor* IntelligentMotorCreator(const std::string& port_name)
   {
     return new T(port_name);
   }

现在我们的映射表变成了

typedef IntelligentMotor* (*Creator)(const std::string& port_name);
   struct Map
   {
     const std::string ModelName;
     Creator DeviceCreator;
   };
   Map model_table[]=
   {
     {"IM9001",&(IntelligentMotorCreator<IM9001>)},
     {"IM9002",&(IntelligentMotorCreator<IM9002>)}
     //...
   };

而ClassByName则变成了

IntelligentMotor* ClassByName(const std::string& model_name,
      const std::string& port_name)
    {
      for (int i=0;i<sizeof(model_table)/sizeof(Map);++i)
      {
        if (model_name==model_table[i].ModelName)
          return (*model_table[i].DeviceCreator)
            (port_name);
      }
      throw "不支持该型号的设备。";
    }

3 扩充

我们现在有了实用的ClassByName,但是还有几个小问题期待我们去解决。

首先,如果查找成为一种费时的操作,那么我们可以使用一个关联数组代替内建数组提供类型查找功能。也就是

typedef std::map<std::string,Creator> ClassLookupTable;
    ClassLookupTable model_lookup_table;
    for (int i=0;i<sizeof(ModelTable)/sizeof(Map);++i)
      model_lookup_table[ModelTable[i].ModelName]
        =ModelTable[i].DeviceCreator;

这时我们的最新版的ClassByName则拥有了略低的平均复杂度。

IntelligentMotor* ClassByName(const std::string& model_name,
      const std::string& port_name)
    {
      ClassLookupTable::const_iterator pos;
      pos=model_lookup_table.find(model_name);
      if (pos==model_lookup_table.end())
        throw "不支持该型号的设备。";
      return (*pos->second)(port_name);
    }

不过这里有一个设计上的决策需要使用者作出,因为这个版本需要更多的时间和空间建立快速查找表,这是一种“一次付出,多次分期摊还成本”的优化策略,必须根据实际情况决定。

其次,为了减低编译依赖性,可以将所有的代码封装成库(或者是共享库,如动态链接库DLL),只输出一个ClassByName接口,并单独提供协议类IntelligentMotor的接口,这样只要不改变协议类的接口,那么使用ClassByName的代码不需要因为增加新型号的设备而重新编译,如果是共享库的形式,那么甚至重新链接都不需要,只需要重新编译独立的设备型号库即可。

无论如何,还是必须手工的为支持每一个新的型号而需要手工修改类型创建器的表格。我实在无法使用模板来处理这种异常古怪的情况

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号