具有Boost和外部数据源的Flyweights

时间:2012-01-13 16:39:16

标签: c++ boost flyweight-pattern boost-flyweight

也许有一种简单的方法,我没有看到,所以希望有人可以向我解释。

假设我有一个班级:

class A {
public:
  const double parameter;
  const std::string name;
  const std:: string fileName;

  A(const double parameter, const std::string name, const std::string fileName) : 
      parameter(parameter), name(name), fileName(fileName) {}; 
};

该类的生成器是:

class AReader {
public:
  ifstream dataFile;
  AReader(const std::string filename);
  A* readObject(const std::string objectName);
};

我想使用boost::flyweight来处理这些A对象,因为它们可能有数百万个引用,实际上它们包含大量数据。它们将在namefileName上进行哈希处理。

我需要做些什么?我需要boost::flyweight来调用AReader.readObject并散列/存储生成的A类。

AReader是否需要成为一个完整的工厂并用作自定义工厂?或者是否可以使用flyweight中的默认工厂,并以某种方式使用AReader生成A实例(而不是实现工厂所需的整个存储模式),可以通过创建{{ 1}}实例对flyweight中的某个东西的参数?或者是否可以从外部数据源获取AReader公共变量(即,一旦设置,它们不会更改),而无需使用第二类?

修改

我也对不使用Boost的其他建议持开放态度。我当然可以编写我自己的flyweight实现,或任何其他模式,如果一个更适合。但如果我可以使用已经存在的东西,那将是最好的。无论什么最小化我需要编写的代码量,因为一如既往,截止日期很短。

3 个答案:

答案 0 :(得分:1)

我没有使用过Boost :: flyweight,但从它的外观来看,至少关键需要是Assignable(除了EqualityComparableHashable)。您输入的const成员显然 Assignable。从它的外观来看,如果你有一个密钥提取器,则不必使它Assignable。使用密钥提取器只需要密钥Assignable

答案 1 :(得分:0)

在你的情况下使用flyweight的基本方法是让readObject返回一个flyweight。 在内部,readObject创建一个全新的对象,当您创建相应的flyweight对象时,它会检查该对象是否已经在flyweight存储区中。如果是这样,它将删除新对象,并返回引用存储中对象的flyweight。如果没有,它会将新对象添加到其池中。

现在,实现起来应该是微不足道的,但根据您的使用情况可能效率低下。为了获得更好的性能,您可以使用key_value功能,该功能允许您通过其键引用对象,并且只有在商店中尚未存在时才创建它们。

答案 2 :(得分:0)

虽然key_value Flyweight似乎符合要求,但似乎有一个小问题。 您应该只使用密钥类型的一个参数(key_value flyweights)来构造key_value Flyweight。因此,为了使它能够使用您想要的密钥(文件名+名称),您必须将这两个字段打包在一个(tuple中?甚至不确定它是否正常工作。)

假设您有兴趣以最少的工作量获得最大收益,那么为什么不只是Flyweight A中所示的字符串,如Flyweight Basics所示?

这意味着{{1}}个对象没有按照您想要的方式进行哈希处理,但字符串很容易被加权,而这些似乎是您的内存问题字段。 (除非这是过于简单化)