我想扩展现有的代码,但是我不确定这样做的最简洁的设计方法。我想知道现有的设计是否真的支持我正在考虑的那种扩展。
有一个工厂,看起来像这样:
class XYZFactory
{
public:
static XYZFactory& getDefaultInstance() // so this is a singleton!
// ... some create methods
// std::unique_ptr<ABC> createABC();
private:
std::unique_ptr<XYZFactoryImpl> m_impl;
}
---
XYZFactory::XYZFactory() : m_impl(std::make_unique<XYZImpl>;
现在的问题是,我想通过派生它来扩展XYZImpl的功能。但是,我想避免在factory类中公开该实现细节,例如添加一个单独的XYZFactory构造函数,并以ExtendedXYZImpl作为参数注入(inject)该扩展名。
为了说明而添加/编辑:我应该叫XYZImpl XYZFactoryImpl。它执行实际的对象创建。 XYZFactory将createWhatever()调用传递给它。只有XYZImpl的一个实例保存在m_Impl中。
我实际上希望能够动态更改的是用于对象创建的XYZImpl m_ABC(ABC实例)的成员。我想从ABC衍生。
杀死XYZFactory的单例设计和子类化会有所帮助吗?
有任何想法吗?
谢谢!
标记
最佳答案
XYZFactory
当前具有对XYZFactoryImpl
的依赖关系,因此很明显,如果不向ExtendedXYZImpl
公开该功能,就无法注入(inject)对XYZFactory
的依赖关系。如果那是 Not Acceptable ,唯一的选择是放弃当前的XYZFactory
设计。
您的问题中没有太多的约束条件供我们用来形成答案,但我建议您首先将XYZFactory
设为抽象工厂:
class XYZFactory {
public:
virtual ~XYZFactory(){}
virtual std::unique_ptr<ABC> createABC() const = 0;
}
有两种实现:
class XYZFactoryImpl : public XYZFactory {
public:
std::unique_ptr<ABC> createABC() const override {
return std::make_unique<ABC>();
}
};
class ExtendedXYZFactoryImpl : public XYZFactory {
public:
std::unique_ptr<ABC> createABC() const override {
return std::make_unique<DerivedABC>();
}
};
然后,您可以提供一个获取单例实例的函数,以及一种使用其他单例实例重新定位的方法。例如:
namespace details {
// Or this could be hidden in an anonymous namespace in a .cpp file
std::unique_ptr<XYZFactory>& getXYZFactoryInstanceMutable() {
static std::unique_ptr<XYZFactory> singleton = std::make_unique<XYZFactoryImpl>();
return singleton;
}
}
const XYZFactory& getXYZFactoryInstance() {
auto& singleton = details::getXYZFactoryInstanceMutable();
if (!singleton)
throw std::runtime_error("No XYZFactory registered");
return *singleton;
}
void setXYZFactoryInstance(std::unique_ptr<XYZFactory> new_factory) {
details::getXYZFactoryInstanceMutable() = std::move(new_factory);
}
然后注入(inject)
ExtendedXYZFactoryImpl
,您可以执行以下操作:setXYZFactoryInstance(std::make_unique<ExtendedXYZFactoryImpl>());
auto abc = getXYZFactoryInstance().createABC();
Live demo。
关于c++ - 扩展此C++工厂实现的最佳方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37021652/