如何指定工厂对象的类型

时间:2012-03-07 19:12:18

标签: c++ design-patterns types factory

我有一个模型视图架构。我想从模型对象创建一个视图对象。 这是一个基本的例子。

如何指定模型对象的类型:枚举(但它们不可扩展),整数(但很容易混淆)......

class ModelA
{
    ModelA(int a);
}

class ModelB : public ModelA
{
    ModelB(int a,int b);
}

class ViewModelA
{
    ViewModelA(ModelA* ma);
}

class ViewModelB : public ViewModelA
{
    ViewModelB(ModelB* mb);
}

class ViewFactory
{
     ModelA * createFromModel(ModelA *ma)
     {
          // Now what is the best way to store type ???
          // Used an integer and overload a static method getType()
          // Or use an enum?
          switch(ma.type)
          {

          }
     }
}


int main(int argc, char *argv[])
{
    ModelA *ma = new ModelA(10);
    ModelA *mb = new ModelB(10,11); 
    ViewFactory myFactory;
    ViewModelA *va = myFactory.createFromModel(ma);
    ViewModelB *vb = myFactory.createFromModel(mb);
    //va should be a model of ViewModelA and vb a model of ViewModelB
}

2 个答案:

答案 0 :(得分:4)

恕我直言,根据您的问题和对其他答案的评论,您也可以在这里使用Visitor pattern。 阅读herehere

因此,Visitor将访问模型层次结构。 Visitor的责任是为访问过的View类型创建适当的Model对象。

然后您不需要存储/声明模型类型。

工作代码:也住在这里:http://ideone.com/9A5bJ

#include <iostream>



class Visitor{
public:
    virtual ~Visitor(){}
    virtual void visitModelA(class ModelA*) = 0;
    virtual void visitModelB(class ModelB*) = 0;
    //add visit functions for later defined models

};





class View{
public:
    virtual ~View(){}
};

class ViewA : public View{
public:
    ViewA(){
        std::cout << "Created ViewA\n"; 
    }
};


class ViewB : public View{
public:
    ViewB(){
        std::cout << "Created ViewB\n"; 
    }
};








class Model{
public:
    virtual ~Model(){}

    virtual void Accept(Visitor* visitor) = 0;

};

class ModelA:public Model{
public:

    virtual void Accept(Visitor* visitor){
        visitor->visitModelA(this);
    }
};

class ModelB:public Model{
public:
    virtual void Accept(Visitor* visitor){
        visitor->visitModelB(this);
    }
};






// ViewCreator can be made a private class of ViewFactory
class ViewCreator : public Visitor{
public:
    virtual void visitModelA(class ModelA*) {
        _view = new ViewA();
    }
    virtual void visitModelB(class ModelB*) {
        _view = new ViewB();
    }

    //add visit functions for later defined models

    View* GetView(){
        return _view;
    }   

private:
    View* _view;
};


class ViewFactory{
public:
    static View* CreateViewFor( Model* model){
        ViewCreator viewCreator;
        model->Accept(&viewCreator);
        return viewCreator.GetView();
    }

};


int main(){

    ModelA modelA;
    View* viewA = ViewFactory::CreateViewFor(&modelA);


    ModelB modelB;
    View* viewB = ViewFactory::CreateViewFor(&modelB);



}

答案 1 :(得分:0)

您需要所有类型的接口:

class ModelIface
{
}
class ModelA : public ModelIface
{
    ModelA(int a);
}

class ModelB : public ModelIface
{
    ModelB(int a,int b);
}

class ViewIface
{
}
class ViewModelA : public ViewIface
{
    ViewModelA(ModelIface* ma);
}

class ViewModelB : public ViewIface
{
    ViewModelB(ModelIface* mb);
}

class ViewFactory
{
     ViewIface * create(ModelIface *ma)
     {
          switch(ma.type)
          {
             case TYPE1:
               return new ViewModelA(ma);
             case TYPE2:
               return new ViewModelB(ma);
             default :
               ;
          }
          return nullptr;
     }
}

TYPE1和TYPE2是否为int,或enum是无关紧要的。

int main(int argc, char *argv[])
{
    ModelIface *ma = new ModelA(10);
    ModelIface *mb = new ModelB(10,11); 
    ViewFactory myFactory;
    ViewModelIface *va = myFactory.createFromModel(ma);
    ViewModelIface *vb = myFactory.createFromModel(mb);
    //va should be a model of ViewModelA and vb a model of ViewModelB
}