我正在开发一个基于依赖注入的 PHP 框架。我的数据对象是可注入的组件,就像其他任何组件一样。
我有一个抽象 DAO 类,每个模型都应该扩展它,它具有:
- 基本的crud方法
- 对 DI 容器的引用,用于实例化对象
简而言之,事情就是这样
abstract class AbstractDao {
protected $fields;
protected $container; // This is the (injected) DI container, used to create instances.
protected $driver; // The injected database driver (i.e. PDO)
public function insert() {
// Insert implementation
// Insert current instance.
}
public function fetch($id) {
// Fetch implementation
// Fetches a row and sets fields on current instance
}
public function fetchAll() {
// Performs a select * query on database driver
// Iterates through results, and creates an instance
// for each result using $container, like this:
foreach ($results as $row) {
// I can't just make $instances[] = new Something(), or all the
// dependency injection thing would mess up.
$instances[] = $this->container->get('someDao');
}
return $instances;
}
// Other methods.
}
class Book extends AbstractDao {
protected $fields = array('field', 'definition', 'goes', 'here',);
// No special behaviour is needed, so we can keep default
// abstract implementation without overriding.
}
我的问题:每个数据对象实现(一本书、一个人、一个用户等)都必须扩展我的 AbstractDao 对象,因此它将承担$driver 和 $container 的重量。此外,由于 $fields 属性是在实例级别定义的,因此每个数据对象都有自己的,增加了更多开销。
我担心在处理大数据集时,就性能而言,此解决方案可能会导致非常昂贵的解决方案。我知道对象只会被引用,而不是被克隆,但开销可能会非常高。
我想到的几个解决方案是
- 使用静态方法实现,可以减少子类的开销
- 不要让我的 Daos 扩展上面提到的 AbstractDao,那应该成为一种 DaoProvider。在这种情况下,对于每种方法,我都应该传入实例(我不太喜欢的东西)
我不太喜欢这些解决方案...首先我不喜欢使用静态的东西,因为它们与注入的整个想法有点冲突。其次,我不喜欢删除 dao 子类模式的想法。
任何好主意将不胜感激,谢谢。
=== 编辑 ===
我又想到了一件事。我不喜欢第二种方法(“dao 提供者”)是提供者必须对 Dao 字段执行操作(设置值、设置状态、设置 isDirty 等),因此必须使字段可以从外部访问. 使用子类化方法可以保持那些受保护的或私有的。
=== /编辑 ===