代码之家  ›  专栏  ›  技术社区  ›  void.pointer

模型对象内部的抽象工厂?

  •  2
  • void.pointer  · 技术社区  · 11 年前

    我有一些Model类和一个控制器(管理器)类。理想情况下,控制器需要处理具体的模型类型,而不进行向下转换(这看起来“正确”)。我想到了访问者模式和抽象工厂模式。以下是我的模型层次结构示例:

    class Animal {};
    class Dog : public Animal {};
    class Cat : public Animal {};
    

    当我的解析器处理数据文件(XML)时,某些元素类型映射到不同的(但相关的)派生类型。在我的示例中,我们的XML定义了不同的动物,我们通过序列化类中的工厂方法将适当的具体类型映射到每个动物(因为它们保存的数据不同,我希望避免充当联合体的单一“animal”类)。但是,这些存储为 Animal 对象,因此它无法知道哪些是猫,哪些是狗。

    当控制器需要以不同于狗的方式处理猫时,我觉得我们可以采取一些方法。

    1. 控制器执行类型的向下转换(dynamic_cast)或检查虚拟类型成员以确定对象是否是猫,然后处理猫。狗也一样。我不太喜欢这个解决方案。
    2. 利用抽象工厂模式,使每个模型知道如何为每个动物类型创建相应的控制器对象。例如 Model::Cat 有一个名为的成员 CreateControllerObject() (多态),并返回 CatController 班请注意,此解决方案的错误之处在于 型号::Cat 类将有一点业务逻辑,例如,在我们知道可以创建cat之前,将进行某些检查。典型的模型对象应该是“哑数据”,所以我不确定是否可以使用“智能”模型。
    3. 直接在Model类上使用访问者模式,但是这需要在模型中放置大量的控制器逻辑,这就是我建议#2的原因。至少在#2的情况下,可以访问相应的具体动物控制器类。

    我不知道如何实现它,所以我想从so社区获得一些设计想法。我自己提出的解决方案中,没有一个感觉是正确的,尽管第二个感觉是最正确的,并且大致朝着正确的方向前进。

    1 回复  |  直到 11 年前
        1
  •  1
  •   MarekR    11 年前

    您可以使用双重调度
    http://en.wikipedia.org/wiki/Double_dispatch

    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