“工厂”方法是正确的模式吗?

时间:2010-03-11 03:56:46

标签: c++ design-patterns factory

所以我正在努力改进现有的实施。我有许多多态类,它们都被组成一个更高级的容器类。我现在要处理的问题是,更高级别的容器类,很糟糕。它看起来像这样,我真的没有问题(因为容器中的多态类应该是公共的)。我真正的问题是构造函数......

/*
 * class1 and class 2 derive from the same superclass
 */
class Container 
{
  public: 
   boost::shared_ptr<ComposedClass1> class1;  
   boost::shared_ptr<ComposedClass2> class2;
  private:
   ...
}

/*
 * Constructor - builds the objects that we need in this container. 
 */ 
Container::Container(some params)
{
  class1.reset(new ComposedClass1(...));
  class2.reset(new ComposedClass2(...));
}

我真正需要的是使这个容器类更易于重用。通过对成员对象进行硬编码并实例化它们,它基本上不是并且只能使用一次。工厂是构建我需要的东西的一种方式(可能通过提供一个对象列表及其要创建的特定类型?)其他方法来解决这个问题?好像有人应该先解决它...谢谢!

6 个答案:

答案 0 :(得分:3)

脑海中浮现出{p> Dependency injection

答案 1 :(得分:0)

如果在派生类中更改创建的类型,即使Container的后代使用class1和class2的不同后代,则使用工厂方法。

class1* Container::GetClass1; virtual;
{
  return new ComposedClass1;
}

class1* SpecialContainer::GetClass1;
{
  return new SpecialComposedClass1;
}

Container::Container(some params)
{
  class1.reset(GetClass1);
  class2.reset(GetClass2);
}

另一种方法是将Container的依赖关系与Container分离。 对于初学者,您可以将构造函数更改为依赖注入class1和class2。

Container::Container(aclass1, aclass2)
{
  class1.reset(aclass1);
  class2.reset(aclass2);
}

答案 2 :(得分:0)

你知道你可以只有第二个没有做到这一点的构造函数吗?

Container::Container(some params)
{
    // any other initialization you need to do
}

然后,您可以随意设置class1和class2,因为它们是公开的。

当然他们不应该这样,但鉴于这个代码就是你可以做的。

据我所知,工厂模式不会那么有用。

答案 3 :(得分:0)

public class factory
{
    public static Class1 Create()
      {
            return new Class1();
      }
}

class Class1
{}
main()
{
   Classs1 c=factory.Create();   
}

答案 4 :(得分:0)

根据您的描述,我建议将一个抽象工厂传递给构造函数。

class ClassFactory {
public:
   virtual ~ClassFactory
   virtual Class1 * createClass1(...) = 0;  // obviously these are real params not varargs
   virtual Class2 * createClass2(...) = 0;
};

class DefaultClassFactory : public ClassFactory {
    //  ....
};


Container::Container(
    some params, 
    boost::smart_ptr<ClassFactory> factory = boost::smart_ptr<ClassFactory>(new DefaultClassFactory))
{
  class1.reset(factory->createClass1(...));
  class2.reset(factory->createClass1(...));
}

这是一种没有框架的依赖注入形式。普通客户端可以像以前一样透明地使用DefaultClassFactory。其他客户端(例如单元测试)可以注入自己的ClassFactory实现。

根据您希望如何控制factory参数的所有权,这可能是smart_ptr,scoped_ptr或引用。该引用可以使语法略微清晰。

Container::Container(
    some params, 
    ClassFactory & factory = DefaultClassFactory())
{
    class1.reset(factory.createClass1(...));
    class2.reset(factory.createClass1(...));
}

void SomeClient()
{
    Container c(some params, SpecialClassFactory());
    // do special stuff
}

答案 5 :(得分:0)

一般来说,我同意汤姆斯评论:没有足够的信息。

根据您的澄清:

  

它只是许多“组件”的容器

如果组件列表不同,请在容器上提供Add / Enumerate / Remove方法。

如果应为容器的每个实例修复组件列表,请使用方法

提供构建器对象
Builder.AddComponent
Builder.CreateContainer

第一个允许重用容器,但在我的经验中往往会变得更复杂。第二个通常需要一种交换/替换容器的方法,但最终更容易实现。

依赖注入库可以帮助您配置应用程序之外的实际类型(尽管我仍然需要了解为什么这是一个如此大的飞跃)。

相关问题