C++ 扩展此C++;工厂实施?
我想扩展一段现有的代码,但我不确定最干净的设计方法是什么。我想知道现有的设计是否真的支持我正在考虑的那种扩展 有一个工厂看起来像这样:C++ 扩展此C++;工厂实施?,c++,design-patterns,factory,C++,Design Patterns,Factory,我想扩展一段现有的代码,但我不确定最干净的设计方法是什么。我想知道现有的设计是否真的支持我正在考虑的那种扩展 有一个工厂看起来像这样: class XYZFactory { public: static XYZFactory& getDefaultInstance() // so this is a singleton! // ... some create methods // std::unique_ptr<ABC> createABC(); private:
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>;
XYZFactory类
{
公众:
静态XYZFactory&getDefaultInstance()//所以这是一个单例!
//…一些创建方法
//std::unique_ptr createABC();
私人:
std::唯一的\u ptr m\u impl;
}
---
XYZFactory::XYZFactory():m_impl(std::make_unique;
现在的问题是,我想通过从XYZImpl派生来扩展XYZImpl的功能。我想避免在factory类中公开该实现细节,比如添加一个单独的XYZFactory构造函数,将ExtendedXYZImpl作为参数来注入该扩展
为澄清而添加/编辑:我应该调用XYZImpl XYZFactoryImpl。它执行实际的对象创建。XYZFactory将createWhatever()调用传递给它。在m_Impl中只有一个XYZImpl实例。
实际上,我希望能够动态更改的是用于对象创建的XYZImpl m_ABC(ABC的实例)的成员
从XYZFactory中删除单例设计和子类化会有帮助吗
有什么想法吗
谢谢大家!
Mark
XYZFactory
目前依赖于XYZFactoryImpl
,因此很明显,如果不在XYZFactory
上公开该功能,就无法注入对ExtendedXYZImpl
的依赖性。如果这是不可接受的,唯一的替代方法是放弃XYZFactory
的当前设计>
您的问题中没有太多的限制因素可供我们用来形成答案,但我建议您首先将XYZFactory
打造成一个抽象工厂:
class XYZFactory {
public:
virtual ~XYZFactory(){}
virtual std::unique_ptr<ABC> createABC() const = 0;
}
不认为有一个完全干净的解决方案,我个人不会损坏一个工厂,我只是改变它,或者如果你想保持代码的独立性,我会考虑一个委托,但是正如我上面所说的,它看起来不那么干净。什么是代码> XYZIMPIL< /代码>?< XYZFactory > /COD>构造函数是什么样子?k:您能详细说明“使用ExtendedXYZImpl作为参数来注入该扩展”是什么意思吗JordZuncK-XYZ将创建方法转发到XYZIML,其中实际对象创建完成。XYZPUT是上面的一个,它只初始化带有XYZImpl的实例的MyIMPL。不确定这是否是C++中的最佳实践?它看起来像抽象的工厂方法,E除了XYZ实际上不是抽象的以外。XYZIPL还有一个对ABC实例的引用,这正是我想要扩展的。ABC被传递给create方法中实例化的一些类的构造函数,但我希望能够传递一个派生的ABC。@shrike Injection是我想要的为了避免这种情况,这是我不想采用的一种示例方法。我当时的想法是将XYZImpl作为参数添加到getDefaultInstance()方法和XYZ构造函数中,这样我就可以注入派生的XYZImpl,而不是创建默认的XYZImpl。
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);
}
setXYZFactoryInstance(std::make_unique<ExtendedXYZFactoryImpl>());
auto abc = getXYZFactoryInstance().createABC();