Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 扩展此C++;工厂实施?_C++_Design Patterns_Factory - Fatal编程技术网

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();