【问题标题】:OO Design issue - is this an anti-pattern, or an appropriate place for a pattern/technique I don't know of?OO 设计问题 - 这是一种反模式,还是我不知道的模式/技术的合适位置?
【发布时间】:2011-12-11 17:42:35
【问题描述】:

我目前正在完成一个 PHP 项目,但 OO 的一般原则仍然适用。

我有一个名为 Node 的父类,它是抽象的 - 即它不能被实例化。有许多扩展 Node 的类,并且是可实例化的。其中一些包括事件、人员和项目。

我遇到的问题是我经常需要实例化一个节点而不知道它将是哪个子类。所有 Node 和节点子类总是将相同类型的对象(数据库中的一行)作为构造函数的参数。为了解决不知道我需要什么类型的实现类的问题,我创建了一个简单的静态类,它将返回正确的节点子类。该代码示例如下:

<?php

class NodeClassRegistry{

    public static function init_class($node) {
        switch ($node->type) {
            case 'person':
                return new Person($node);

            case 'event':
                return new Event($node);
        }
    }

}

?>

这对我来说似乎是非常糟糕的设计——它是一种工厂模式,但它似乎真的与全局状态相关联。是否有适合这种情况的设计模式?

【问题讨论】:

    标签: oop design-patterns inheritance


    【解决方案1】:

    您所做的是Factory Method design pattern 的特殊类型GoF book 中此子类型的 C++ 示例如下:

    class Creator {
    public:
      virtual Product* Create(ProductId id);
    }
    
    Product* Creator::Create(ProductId id) {
      if (id == MINE) return new MyProduct;
      if (id == YOURS) return new YourProduct;
      ...
      return 0;
    }
    

    【讨论】:

      【解决方案2】:

      这是Abstract Factory 设计模式,依靠某种type 字段/变量来检查工厂应该创建哪个底层类型的实例是非常好的。请参阅 Java 语言上的抽象工厂实现示例,它从配置文件中读取全局变量...

      【讨论】:

        【解决方案3】:

        在 C# 中,我会将完整的类名存储在一列中并使用反射创建它。如果我没记错的话,我可以应用“约定优于配置”,即:

        创建名称等于类型列中的值的类

        然后,创建一个这样的函数:

        public static function init_class($node) {
            $item = NULL;
            eval "\$item = new " . $node->type . "(\$node);"
            return $item;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多