前言:我试图在关系数据库的MVC架构中使用存储库模式。
我最近开始学习PHP中的TDD,我意识到我的数据库与应用程序的其余部分耦合得太紧密了。我读过关于存储库和使用IoC容器将其“注入”到我的控制器。非常酷的东西。但是现在有一些关于存储库设计的实际问题。考虑下面的例子。
<?php
class DbUserRepository implements UserRepositoryInterface
{
protected $db;
public function __construct($db)
{
$this->db = $db;
}
public function findAll()
{
}
public function findById($id)
{
}
public function findByName($name)
{
}
public function create($user)
{
}
public function remove($user)
{
}
public function update($user)
{
}
}
所有这些查找方法都使用select All fields (SELECT *
)方法。然而,在我的应用程序中,我总是试图限制我获得的字段数量,因为这通常会增加开销并降低速度。对于使用这种模式的用户,如何处理这种情况?
虽然这个类现在看起来不错,但我知道在真实的应用程序中,我需要更多的方法。例如:
如你所见,可能有一个非常非常长的方法列表。然后,如果您添加了上述字段选择问题,问题就会恶化。在过去,我通常只是把所有这些逻辑放在我的控制器中:
<?php
class MyController
{
public function users()
{
$users = User::select('name, email, status')
->byCountry('Canada')->orderBy('name')->rows();
return View::make('users', array('users' => $users));
}
}
使用我的存储库方法,我不想以这样的结果结束:
<?php
class MyController
{
public function users()
{
$users = $this->repo->get_first_name_last_name_email_username_status_by_country_order_by_name('Canada');
return View::make('users', array('users' => $users))
}
}
我看到了为存储库使用接口的好处,因此我可以替换我的实现(用于测试或其他目的)。我对接口的理解是,它们定义了实现必须遵循的契约。这很好,直到你开始向你的存储库添加额外的方法,如findAllInCountry()
。现在我需要更新我的接口来拥有这个方法,否则,其他实现可能没有它,这可能会破坏我的应用程序。这感觉很疯狂…这是一个因小失大的例子。
这让我相信存储库应该只有固定数量的方法(如save()
, remove()
, find()
, findAll()
等)。但是如何运行特定的查找呢?我听说过规范模式,但在我看来,这只减少了整个记录集(通过IsSatisfiedBy()
),这显然有主要的性能问题,如果你从数据库中提取。
显然,在使用存储库时,我需要重新考虑一些事情。有谁能告诉我这个最好怎么处理吗?