我正在使用 Table-Data-Gateway 模式。我所有不是 Mappers 或 DB_Table 类的模型都扩展了 Model_Base。我所有的映射器都扩展了Model_MapperBase
. 我所有的 DB_Table 类都扩展了Zend_Db_Table_Abstract
.
在我所有的映射器类中,我想强制有一个函数map
,它接受一个DB_Row
对象,以及映射到的模型类。理想情况下,我希望能够做的是在 my 中Model_MapperBase
,我会:
abstract public function map(Model_Base $model, Zend_Db_Table_Row_Abstract $row);
然后当我实现它时,我会这样做:
public function map(Model_User $user, Zend_Db_Table_Row_Abstract $row) {
$user->setId($row->id)
->setName($row->name);
return $user;
}
但显然,这不起作用,因为抽象函数说它应该采用任何扩展 Model_Base 的类。但我想确保,是的,它必须是扩展 Model_Base 之一,但我希望实现更具体。
我唯一能想到的就是:
public function map(Model_Base $user, Zend_Db_Table_Row_Abstract $row) {
if (get_class($user) != 'Model_User') {
throw new Exception('Invalid Class');
} else {
$user->setId($row->id)
->setName($row->name);
return $user;
}
}
但这似乎在一定程度上是错误的。有一个更好的方法吗?
编辑:因此,对以下内容不满意,我采取了以下措施:
final public function map(Model_Base $model,
Zend_Db_Table_Row_Abstract $row)
{
if (get_class($this) != get_class($model).'Mapper') {
throw new Exception("Invalid Class: Expected " . substr(get_class($this), 0, strlen($this)-6) . '. Received ' .
get_class($model) . '.');
}
return $this->mapImplementation($model, $row);
}
abstract protected function mapImplementation(Model_Base $model,
Zend_Db_Table_Row_Abstract $row);
然后让我的 Mapper 类实现 mapImplementation 方法,但始终调用 map 方法。这有效地完成了我想要的,但似乎有点做作,并且只是碰巧起作用,因为截至目前,我所有的 Mapper 类都有一个同名的类,没有“映射器”。
有没有更好的方法来完成我想要做的事情,它不依赖于命名方案或在每个类中抛出异常?
编辑:我不是在寻找“使用 instanceOf 而不是 get_class”——这对于我的目的来说本质上是一样的,如果我打算扩展我的非基础映射器类,我会做出改变。我正在寻找一种方法来强制执行正确的类类型,而无需手动抛出异常。