我目前正在用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);
}
}
}
?>
对我来说,这似乎是一个非常糟糕的设计 - 它是一种工厂模式,但它似乎与全球状态紧密相连。是否有适合这种情况的设计模式?
答案 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;
}