我想扩展现有的代码,但是我不确定这样做的最简洁的设计方法。我想知道现有的设计是否真的支持我正在考虑的那种扩展。

有一个工厂,看起来像这样:

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/

10-11 00:19