与PHP框架的依赖注入相结合的DAO模式是什么?
我正在开发一个基于依赖注入的
PHP框架.我的数据对象是可注入的组件,与其他任何组件一样.
我有一个抽象的DAO类,每个模型都应该扩展,它具有: >基本的方法 简而言之,事情就像这样 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属性是在实例级别定义的,因此每个数据对象都有自己的属性,从而增加了更多的开销. 我担心在处理大数据集时,就性能而言,这种解决方案可能会导致成本过高.我知道对象只会被引用,而不是克隆,但开销可能会高得惊人. 我想到的几个解决方案是 >使用静态方法实现,可以减少开销 我不喜欢那些解决方案…首先我不喜欢使用静态的东西,因为它们与注射的整个想法有点冲突.其次,我不喜欢删除dao子类模式的想法. 非常感谢任何好主意,谢谢. ===编辑=== 还有一件事在我脑海里浮现.在第二种方法(“dao provider”)中我不喜欢的是提供者必须对Dao字段(设置值,设置状态,设置isDirty等)执行操作,因此必须从外部访问字段.使用子类化方法,可以保护受保护的或私有的. === /编辑=== 解决方法
我建议你创建一个DAO接口来声明DAO实现必须定义的行为.现在,在每个具体的DAO实现中,您可以定义$driver,$container和$fieldsinstance字段.
之后,您可能希望创建一个AbstractModelclass,每个具体模型都应该扩展,以便您的AbstractModeland具体模型都将“数据访问不可知”. AbstractModel类最终将如下所示: /* * an AbstractModel */ abstract class AbstractModel { protected $daoImpl; function __construct(DAOInterface $daoImpl) { $this->daoImpl = $daoImpl; } //some other functions that are common to concrete models } /* * a concrete model */ class Model extends AbstractModel { function findAll($params) { //You can use the $daoImpl of AbstractModel to perform a CRUD operation $this->daoImpl->findAll($params); } } 现在,无论何时实例化具体模型,都会将DAO实现注入模型类. //inject a DAOInterface implementation into Model $model = new Model(new DAOImpl()); $model->findAll($params); 这里的优点是你可以在测试期间存根不同的DAO实现,也许这就是DI容器派上用场的地方.几天前我创建DI容器时创建了一个similar code sample. 顺便说一下,我没有看到需要在您的AbstractDAO中放入$containerobject,为什么不传入调用容器属性时返回的对象.这样你可以使用type hinting来强制对象参数属于某种类型,并且如果传入了错误的对象,则鼓励使用快速失败的机制,你也可能会发现创建一个Config类来处理你的$driver细节是有益的用户可以自由配置他们想要用于db的驱动程序. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |