C++ 模型对象内部的抽象工厂?
我有一些模型类和一个控制器(管理器)类。理想情况下,控制器需要在不进行向下转换的情况下处理具体的模型类型(这似乎是“正确的”)。我想到了访问者模式和抽象工厂模式。以下是我的模型层次结构示例:C++ 模型对象内部的抽象工厂?,c++,model-view-controller,C++,Model View Controller,我有一些模型类和一个控制器(管理器)类。理想情况下,控制器需要在不进行向下转换的情况下处理具体的模型类型(这似乎是“正确的”)。我想到了访问者模式和抽象工厂模式。以下是我的模型层次结构示例: class Animal {}; class Dog : public Animal {}; class Cat : public Animal {}; 当我的解析器处理数据文件(XML)时,某些元素类型映射到不同(但相关)的派生类型。在我的示例中,我们的XML定义了不同的动物,我们通过序列化类中的工厂方
class Animal {};
class Dog : public Animal {};
class Cat : public Animal {};
当我的解析器处理数据文件(XML)时,某些元素类型映射到不同(但相关)的派生类型。在我的示例中,我们的XML定义了不同的动物,我们通过序列化类中的工厂方法将适当的具体类型映射到每个动物(因为它们所持有的数据不同,我希望避免充当联合体的单一“动物”类)。但是,这些对象在控制器中存储为动物
对象的列表,因此它无法知道哪些是猫,哪些是狗
当控制器需要以不同于狗的方式处理猫时,我觉得我们可以采取一些方法
Model::Cat
有一个名为CreateControllerObject()
(多态)的成员,并返回一个CatController
类。请注意,这个解决方案的错误之处在于Model::Cat
类将有一点业务逻辑,例如,在我们知道可以创建Cat之前将进行某些检查。通常,模型对象应该是“哑数据”,所以我不确定使用“智能”模型是否合适我不知道如何实现它,所以我想从so社区获得一些设计想法。我自己提出的解决方案没有一个是正确的,尽管#2感觉最正确,方向大致正确。您可以使用双重分派
使用访问者模式,控制器逻辑将进入具体的访问者中,而不是模型中。@Jarod42我的想法正是如此#我的列表中的3提到了这一点,但它们的关键是我需要一个对应的控制器层次结构来存储控制器逻辑本身,从而实现访问者。如果
controller
派生自IAnimalVisitor
,则将是双重分派。实际上,这是一个简单的分派。@Jarod42维基百科的文章使双重分派看起来需要两个vtable查找。这里的解决方案只涉及一个查找,但涉及两个函数调用,因此按照该标准它不是双倍的(但似乎是一个任意规则)。另外,您是否建议update()
进入模型类?让我的模特做这个可以吗?或者我应该通过创建相应的控制器对象(即DogController::update()
)来创建另一个抽象吗?即使您创建了一个DogController,您也必须使用此解决方案将其放在模型类的某个位置。另一个解决方案是在创建时将Dogs/Cats添加到单独的容器中,然后在运行时不必进行动态类型检查。
class Controller
{
public:
void update_animal(Dog &dog) { ... }
void update_animal(Cat &cat) { ... }
};
class Dog : public Animal
{
public:
virtual void update(Controller &controller)
{
controller.update_animal( *this );
}
}
// same for Cat