我试图设计一个类,它封装了一些数据的处理,结果的缓存以及通过成员函数访问结果。
我目前的设计如下:
class DataProcessor
{
public:
DataProcessor();
void populateUsing(const rawDataSource &source);
// Must call populateUsing() first!
int getDataX() const;
int getDataY() const;
};
还有一个额外的约束:提供的rawDataSource
的生命周期可能会在调用populateUsing()
和getData[XY]()
之间变为无效
在达到这个设计之前,我经历了各种选择,包括:
rawDataSource
参数传递给构造函数isPopulated
标志,由getDataX()
等检查,然后可以抛出异常,返回错误值,或者自己调用populateUsing()
。备选方案1有效,但不充分,因为处理可能需要很长时间,如果getData[XY]()
未被调用,则实际上可能不需要。我想按需执行处理。
备选方案2并不足以:
populateUsing()
无法被调用,因为rawDataSource
无法保证仍然有效我的总体目标是提供易于使用且难以滥用的类界面。执行一个只有评论的成员函数调用命令似乎违反了我的“难以滥用”#39;目标
根据我的约束条件,首选设计是什么?如果您发现在实践中是最好的,请随意提名我的替代方案。
(这个问题最好发布给programmers.SE吗?)
答案 0 :(得分:2)
考虑你的两个主要“目标”
我正在尝试设计一个封装了某些处理的类 数据,结果的缓存以及通过成员访问结果 功能
和
我的总体目标是提供一个易于使用的类接口 使用和难以滥用。执行成员函数调用顺序 只有评论似乎违反了我的“难以滥用” 目标
我会阻止客户做出所有决定和评估。
怎么样?
class DataProcessor {
public:
int getDataX(const rawDataSource &source); // Probably you should rename the methods
int getDataY(const rawDataSource &source);
};
int DataProccessor::getDataX(const rawDataSource &source) {
// Process data if not already cached and valid
// return cached data
}
int DataProccessor::getDataY(const rawDataSource &source) {
// Process data if not already cached and valid
// return cached data
}
这样您就可以根据需要处理数据。您可以检查您的数据是否已经处理并且仍然有效。
答案 1 :(得分:0)
我认为我的课真的应该是这样的:
class DataProcessor
{
private:
// Moved to private. Now called by the constructor.
void populateUsing(const rawDataSource &source);
public:
DataProcessor(const rawDataSource &source);
int getDataX() const;
int getDataY() const;
};
将populateUsing()
作为公共职能的原因是允许(可能是密集的)处理发生时的灵活性。
但是,调用者仍然可以通过在需要时(或者当所需的rawDataSource有效时)创建DataProcessor
对象来控制处理时间。