2012-01-13 64 views
7

也许有一个简单的方法可以解决这个问题,我没有看到,所以希望有人能向我解释。配重和外部数据源的Flyweights

比方说,我有一个类:

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是否需要成为一个完整的工厂并用作自定义工厂?或者是否有可能使用轻量级中的默认工厂,并以某种方式使用AReader来生成A实例(而不是实现工厂所需的整个存储模式),也许通过使一个AReader实例成为flyweight中的某个参数的参数?或者是否有可能从外部数据源获取const公共变量(即一旦设置,它们不会改变),而不诉诸第二类?

编辑

我也开不使用Boost其他建议。我当然可以编写我自己的轻量级实现,或者更适合的其他模式。但是如果我可以使用已经存在的东西,那最好。无论如何最小化我需要编写的代码量,因为与往常一样,截止日期很短。

回答

1

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

+0

这需要做什么才能将'A'变成flyweight(键提取器而不是可分配的),但是使用生成'A'的辅助类的唯一方法是使它成为flyweight使用的完整工厂(实现存储和其他所需的方法)? – tpg2114 2012-01-14 11:47:18

0

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

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

0

尽管一个Flyweight似乎符合法案,它似乎有一个小小的麻烦。 您应该能够通过仅使用密钥类型的一个参数(key_value flyweights)构建一个享元。因此,为了使它与你想要的密钥(文件名+名称)一起工作,你必须将这两个字段合并为一个(tuple?甚至不能确定它会工作。)

假设你有兴趣获取大部分工作量最少,为什么不是Flyweight班级中的字符串如Flyweight Basics所示?

这意味着A对象不散列你想要的方式,但字符串容易flyweighted,而这些似乎是你的内存有问题的领域。 (除非这是一个过于简单化)