用于将对象创建与其类分离的模式

时间:2011-11-22 18:36:31

标签: c++ design-patterns

假设我有一个Class Foo,它有许多内部变量,只有一个构造函数和非修改方法。 内部变量值的计算涉及状态变量和复杂函数,因此不应该是Foo的一部分。因此,我创建了一个执行微积分的类FooCreator,最后创建了Foo。

首先,我在FooCreator中分别实现了创建Foo所需的所有成员变量,并添加了一个createFoo()函数,但最后FooCreator几乎变成了Foo的副本以及更多的状态变量。

接下来,我决定让FooCreator继承Foo,这样可以省去很多打字 这只是感觉不是一个干净的解决方案,因为获得某事。我必须使Foo的成员变量受到保护而不是私有,因此暴露出比我想要的更多其他用户。除了创建之外,不应该将Foo用作基类。

我看了一下工厂模式,但这似乎有点矫枉过正。 当然这个问题会非常普遍。那么处理这个问题的正确方法是什么呢?

一些代码示例如下所示:

class Foo{
    private: //protected for second case
      int mVal;
      State mState;
      ComplexStuff mStuff;
      //...

    public:
      Foo():mVal(),mState(),mStuff(){}
      Foo(int val, State const& state, ComplexStuff const& stuff):
        mVal(val),mState(state),mStuff(stuff){}
      bool loadFromFile();

      bool evalStateTransition(State const& formerState) const{/*....*/}
      bool someTest(int) const{/*....*/};
      GraphicItem* visualize() const{/* ....*/};
      //...  
  };

  class FooCreator{  
    private:
      int mVal;
      State mState;
      ComplexStuff mStuff;

      StuffVisualizer mStuffVis;
      Paramset mParams;    
      //...

    public:
      FooCreator(Paramset const& set):
        mVal(),mState(),mStuff(),mStuffVis(),mParams(set){}
      constructState(int, int, int);
      gatherStuff1(File file1);
      Foo createFoo();

      int evalStateTransition(State const& formerState)  const{
        /*same long code as in Foo*/
      }
      bool someTest(int) const{ /*same long code as in Foo*/}
      GraphicItem* visualize() const{ /*same long code as in Foo*/}
      //...  
  };

  class FooCreator2 : public Foo{  
    private:
      StuffVisualizer mStuffVis;
      Paramset mParams;    
      //...

    public:
      FooCreator(Paramset const& set):Foo(),mParams(set){}
      constructState(int, int, int);
      gatherStuff1(File file1);
      Foo createFoo();    
  };

2 个答案:

答案 0 :(得分:1)

It can be good to keep complex logic out of the constructor。但是,如果您不想使用工厂构建器模式,则可以提取ParameterObject

如果您需要使用Foo中的方法来创建实例,那么您可能应该尝试将Foo拆分为两个类。

答案 1 :(得分:1)

只需在Foo中编写friend class FooCreator;,现在您可以从FooCreator访问Foo的所有私有字段。然后在FooCreator中创建一个Foo类型的字段......很好,很简单。