关于抽象工厂和注射的问题

Mar*_*ark 6 c++ oop design-patterns

这与我的其他问题类似,但我认为不同的是保证一个新问题.

基本上我正在编写用户界面,我的用户界面有可以选择的节点.当选择节点时,用户界面以抽象节点基类"INode"结束.从这个我做节点 - > getFactory(),并从这个我可以创造此时,相应的对话框或观看该节点,因为正确的工厂得到由混凝土节点返回(如出厂> createAddDialog(),出厂时得到一个工厂> createView(节点)等).

我的问题是,试图找到该工厂进入摆在首位的节点的最佳途径.

到目前为止,我已经想到了3种方法:

1)创建节点时注入正确的工厂:

AreaNode *node = new AreaNode(new AreaNodeFactory());
Run Code Online (Sandbox Code Playgroud)

所以AreaNode的定义是:

AreaNode : public INode
{
    AreaNode(INodeAbstractFactory *injectedFactory)
    {
        m_injectedFactory = injectedFactory;
    }

    INodeAbstractFactory* getFactory()
    {
        return m_injectedFactory;
    }

    INodeAbstractFactory* m_injectedFactory;
};
Run Code Online (Sandbox Code Playgroud)

2)注入一个更通用的工厂并允许节点从该工厂获得工厂:

AreaNode : public INode
{
    AreaNode(IFactory *injectedFactory)
    {
        m_injectedFactory = injectedFactory;
    }

    INodeAbstractFactory* getFactory()
    {
        return m_injectedFactory->getAreaNodeFactory();
    }

    IFactory* m_injectedFactory;
}
Run Code Online (Sandbox Code Playgroud)

3)只需创建具体工厂(尽管这样就删除了为同一节点使用不同工厂的范围,可能用于测试或以后的更改):

AreaNode : public INode
{
    INodeAbstractFactory* getFactory()
    {
        return new AreaNodeFactory();
    }
}
Run Code Online (Sandbox Code Playgroud)

目前关于这些选择的想法:

选项1:可能是有点杂乱无章 - 我必须确保我总是给它正确的工厂为该类型,也许我可以只使用另一家工厂注入正确的工厂给我.

选项2:强制了解抽象工厂实现足以能够调用getAreaNodeFactory,这可能不是一件坏事节点.它至少有助于确保始终获取正确/相同的工厂(假设更一般的工厂正确实施).

方案3:这种感觉,因为我不能够交换类出一点限制,我并不热衷于为了解具体执行工厂的节点 - 尽管在这种情况下,它可能不会太大一个问题(着名的遗言!).

有什么想法吗?

谢谢.

编辑:抱歉错过了原始帖子中的变量声明,更正了.

编辑:选项2的另一个问题是我必须在每个节点类型中实现"getFactory".至少对于选项1,基类每次都可以返回注入抽象工厂类.

MSa*_*ers 2

怎么样

class FactoryBase { /* interface */ }
template <typename NodeType> class Factory : public FactoryBase {
  // Default implementation.
}
// Add appropriate specializations for all relevant nodetypes, if needed.
template <typename NodeType> inline Factory<NodeType> getFactory(NodeType*) {
  return Factory<NodeType>( );
}

class AreaNode : public Node {
  FactoryBase getFactory() { return getFactory(this); }
};
Run Code Online (Sandbox Code Playgroud)

模板参数推导将确保工厂类型派生自this. 这应该可以防止出现手动错误。但总的来说,我根本不会费心去公开曝光一家工厂。只需将以下位添加到基类中:

class Node {
public:
  std::Auto_ptr<View> createView( ) {
    this->getFactory()->createView(this);
  } // etc.
private:
   virtual FactoryBase* getFactory() = 0;
};
Run Code Online (Sandbox Code Playgroud)