【发布时间】:2014-05-07 04:07:27
【问题描述】:
这是一个关于给定问题的 C++ 中特定 OO 实现的问题:
算法有几种变体,比如说两种,它们都有一些通用部分。这些算法(它们的实现,AlgImpl)接收启动选项。他们还接收输入数据,并逐个处理这些数据。有不同的方式可以提供启动选项(来自文件、来自网络、来自用户输入),以及接收数据的不同方式(来自文件、来自设备)。对于不同的数据源,有一个通用的 API,对于选项也是如此。
架构应该允许使用任何可用的 AlgImpl 以及任何可用的选项和数据源。它还应该允许添加新的 AlgImpl 和可能的新类型的选项和数据源,而对原始代码的更改最少或不更改(比如说只有两个 AlgImpl、两个选项源类型和两个数据源类型)。
这是我对 C++ 的看法,使用继承、聚合和指针。由于所有 AlgImpl 都共享一些公共部分,因此很自然地围绕一个基本抽象类来组织它们,因此(省略非必要的数据类型)我们有:
class BaseAlgorithm
{
... //Abstract class with common code
};
class SimpleAlgorithmImpl: public BaseAlgorithm
{
...
};
class OptimalAlgorithmImpl: public BaseAlgorithm
{
...
};
现在,选项和数据源分别具有相同的界面:
class BaseOptionsSource
{
public:
//Interface
virtual void GetOptions(Options& opts) = 0;
};
class FileOptionsSource: public BaseOptionsSource
{
void GetOptions(Options& opts);
...
};
class NetworkOptionsSource: public BaseOptionsSource
{
void GetOptions(Options& opts);
...
};
class BaseDataSource
{
public:
//Interface
virtual void GetDataChunk(DataChunk& chunk) = 0;
};
class FileDataSource: public BaseDataSource
{
void GetDataChunk(DataChunk& chunk);
...
};
class DeviceDataSource: public BaseDataSource
{
void GetDataChunk(DataChunk& chunk);
...
};
然后将选项和数据源设为 BaseAlgorithm 的成员:
class BaseAlgorithm
{
public:
BaseAlgorithm(BaseDataSource* pDataSrc, BaseOptionsSource* pOptsSrc);
BaseDataSource* _pDataSrc;
BaseOptionsSource* _pOptsSrc;
};
BaseAlgorithm::BaseAlgorithm(BaseDataSource* pDataSrc, BaseOptionsSource* pOptsSrc):
_pDataSrc(pDataSrc), _pOptsSrc(pOptsSrc)
{
}
然后可以按如下方式创建特定的算法对象:
DeviceDataSource dataSrc;
NetworkOptionsSource optsSrc;
SimpleAlgorithmImpl simpleAlg(&dataSrc, &optsSrc);
对于新的 AlgImpl 或新类型的源,其类应实现继承的方法。当然,必须有一个“if/else if/...”代码,在创建 AlgImpl 对象之前明确选择使用的 AlgImpl 和源的集合。
在这种情况下,源对象也可以被重用,前提是 AlgImpl 对象不管理传递给它的源对象的分配/解除分配。
您认为这是在 C++ 中执行此操作的正确方法吗?或者,对于这种可互换的子功能实现,是否存在其他更简单、更灵活或更少“无问题”的模式?这种情况下是不是就不能避免使用指针了?
【问题讨论】:
标签: c++ pointers inheritance aggregation