OO设计问题 - 这是一个反模式,还是我不知道的模式/技术的适当位置?

时间:2011-12-11 17:42:36

标签: oop design-patterns inheritance

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

我有一个名为Node的父类,它是抽象的 - 即它无法实例化。有许多类可以扩展Node,并且是可实例化的。其中一些包括Event,Person和Project。

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

<?php

class NodeClassRegistry{

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

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

}

?>

对我来说,这似乎是一个非常糟糕的设计 - 它是一种工厂模式,但它似乎与全球状态紧密相连。是否有适合这种情况的设计模式?

3 个答案:

答案 0 :(得分:2)

您所做的是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;
}

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

创建名称等于类型列

中找到的值的类

然后,以这种方式创建一个函数:

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