扩展此C ++工厂实现的最佳方法是什么?

时间:2016-05-04 07:52:22

标签: c++ design-patterns factory

我想扩展现有的一段代码,而且我不确定最干净的设计方法。我想知道现有的设计是否真的支持我正在考虑的那种扩展。

有一家工厂看起来像这样:

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的功能。我想避免在工厂类中公开该实现细节,例如添加一个单独的XYZFactory构造函数,并将ExtendedXYZImpl作为参数来注入该扩展。

ADDED / EDITED澄清:我应该调用XYZImpl XYZFactoryImpl。它完成了实际的对象创建。 XYZFactory将createWhatever()调用传递给它。只有一个XYZImpl实例保存在m_Impl中。 我实际上想要能够动态改变的是XYZImpl m_ABC(ABC的实例)的成员,它用于创建对象。我想从ABC那里得到。

从XYZFactory帮助杀死单例设计和子类化吗?

有什么想法吗?

谢谢!

标记

1 个答案:

答案 0 :(得分:0)

XYZFactory目前依赖于XYZFactoryImpl所以很明显没有办法在ExtendedXYZImpl上注入依赖关系,而不会在XYZFactory上公开该功能。如果这是不可接受的,唯一的选择是放弃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>();
  }
};

然后,您可以提供一个函数来获取单例实例以及使用不同的单例实例重新设置的方法。 e.g:

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

然后注入你可以做的ExtendedXYZFactoryImpl

setXYZFactoryInstance(std::make_unique<ExtendedXYZFactoryImpl>());

auto abc = getXYZFactoryInstance().createABC();

Live demo