【发布时间】:2015-04-27 04:07:39
【问题描述】:
假设我有以下类,它们的实例存储它们的属性 somewhere for e.x.在 JSON 文件或数据库中:
类 Foo
abstract class Foo
{
protected $ID;
protected $title;
// getters and setters
}
类栏(扩展 Foo)
class Bar extends Foo
{
protected $text;
// getters and setters
}
Baz 类(也扩展 Foo)
class Baz extends Foo
{
protected $tabs = array();
// getters and setters
}
从数据源加载它们的最佳方式是什么?
我现在怎么做(不满意)
我的抽象类Foo 有一个方法load($ID, PDO $pdo)。此方法被Bar 和Baz 覆盖,这扩展了Foo 类中title 属性的一般加载,具有必须加载的它们自己的属性。
所以在代码中它看起来像这样:
类 Foo
abstract class Foo
{
protected $ID;
protected $title;
public static function load($ID, PDO $pdo)
{
$result = null;
// SQL query for getting $title property into $result
return $result;
}
// getters and setters
}
在 Bar 类中,我这样做:
class Bar extends Foo
{
protected $text;
public function __construct(stdClass $data)
{
$this->ID = $data->ID;
$this->text = $data->text;
}
public static function load($ID, $pdo)
{
$generalInfo = parent::load($ID, $pdo);
$result = null;
// PDO query for getting $text property into $result
$generalInfo->text = $result;
return $generalInfo;
}
// getters and setters
}
所以这让我调用 $dataToCreateInstance = Bar::load(4, $pdoInstance) 并返回所需的信息来实例化 ID 为 4 的特定 Bar 对象。
这里的问题是(如您所见)我的类绑定到 PDO,而且为每个数据源实现 load 方法真的很难看,所以它根本不是通用的。
我想要达到的目标
我现在正在寻找一种模式,可以让我从任何来源加载这些类。我想到了一个看起来像这样的Loader 类:
class LoaderManager
{
/**
* @var Loader[]
*/
protected $loaders = array();
public function registerLoader($className, $loaderClass)
{
$this->loaders[$className] = $loaderClass;
}
public function loadClass($class, $ID)
{
return $this->loaders[$class]->load($ID);
}
}
还有一个抽象的 Loader 类
abstract class Loader
{
public abstract function load($ID);
}
所以现在我已经解耦了。这个尝试的问题是我总是为类本身提供一个额外的Loader。所以对于Bar 类,我必须至少提供BarLoaderPDO 或BarLoaderJSON 之一。这在某种程度上不是那么优雅,感觉有点“错误”。
还有一个问题是我必须将当前应用程序中的哪个类必须使用哪个加载器的映射存储在某个地方。
但这是我能想到的唯一尝试,它使我达到了我想要实现的目标。
我现在想讨论和听听是否有其他(更好的)尝试以及如何实现它们。
【问题讨论】:
标签: php design-patterns logic