Как указать тип для заводских объектов - PullRequest
1 голос
/ 07 марта 2012

У меня есть модель представления архитектуры. Я хочу создать видовой объект из модельного объекта. Вот базовый пример.

Как мне указать тип объектов моей модели: перечисления (но тогда они не расширяемы), целые числа (но потом легко запутаться) ...

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 ]

4 голосов
/ 07 марта 2012

ИМХО, из вашего вопроса и комментария к другому ответу вы также можете использовать Шаблон посетителя здесь.Прочтите об этом здесь или здесь

Итак, иерархию модели посетит 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);



}
0 голосов
/ 07 марта 2012

Вам нужны интерфейсы для всех типов:

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
}
...