使用外部数据源实现域模型和数据映射器模式
更新:
确定一些更新,最后我们决定了框架(Yii)并且有一些初始结构。 我将粘贴一些相关代码来说明我们的当前状态:(只有阅读动作在这里)
调节器
class SponsorController extends RestController
{
public function actionRestView($id)
{
$sponsorMapper = new SponsorMapper(
new Db1Adapter(), // Gateway to the external SOAP Webservice
new Db2Adapter() // Gateway to the external REST Webservice
);
$data = $sponsorMapper->read($id);
$this->renderJson(
array(
'success' => true,
'message' => 'Record Retrieved Successfully',
'data' => $data
)
);
}
}
领域模型
class Sponsor extends CModel
{
public $id;
public $db1Result;
public $db2Result;
public function attributeNames()
{
return array(
'id',
'db1Result',
'db2Result',
);
}
}
数据映射器
class SponsorMapper extends Mapper
{
public function __construct(SoapAdapter $db1Adapter,
RestAdapter $db2Adapter)
{
$this->adapters['soap'] = $db1Adapter;
$this->adapters['rest'] = $db2Adapter;
}
public function read($id)
{
$db1Result = $this->adapters['soap']->demoRequest();
$db2Result = $this->adapters['rest']->demoRequest();
return $this->createEntity($db1Result, $db2Result);
}
protected function createEntity($db1Result, $db2Result)
{
$sponsor = new Sponsor();
$sponsor->db1Result = $db1Result;
$sponsor->db2Result = $db2Result;
return $sponsor;
}
}
现在我有两个问题:
现在,Sponsor对象的属性只是db1Result和db2Result,我将它更改为实际属性(例如firstName,lastName,email),因此SponsorMapper :: createEntity将如下所示:
protected function createEntity($db1Result, $db2Result)
{
$sponsor = new Sponsor();
$sponsor->firstName = $db1Result->result->first_name;
$sponsor->lastName = $db1Result->result->last_name;
$sponsor->email = $db2Result->QueryResult->ItemObject->email;
return $sponsor;
}
在我看来,这些类型的东西应该发生在域对象,而不是映射器; 我知道我可以将db1Result和db2Result视为自己的域对象,并将它们的关系创建为Sponsor域对象,但我不确定这是否是正确的方向。 我应该在制图员那里做吗?
初始问题:
我们正在设计/创建一个基于PHP MVC框架的RESTFul API项目。 该项目的目标是作为两个其他“外部”API(一个SOAP,另一个REST)之间的适配器。
我认为这个项目中的模型应该像这样工作:
所以我们有这些模型:
现在我不喜欢这个设计,这个结构有点复杂,我不知道一个好的方法来把这些模型文件放到不同的地方,根据它们的“类型”(用户模型本身,构建器模型等)。
我是否过度设计了这个? 我应该考虑更好的模式吗?
MVC中没有“多个模型”。 模型是构成MVC设计模式的两层中的一层(与表示层一起)。 人们通常所说的“模型”实际上是域对象。 你可能会发现这个相关的。
这就是说,你看着这一切都是错误的。 你现在有什么是活动记录模式的变化。 只有在这种情况下,存储介质不是数据库,而是REST API和/或SOAP接口,而不是传统的SQL存储。
在这种情况下,最好的选择是将域对象(例如: User
)与存储相关逻辑的不同元素分开。 我个人更喜欢为此实现数据映射器。 实质上,如果您有一个域对象,则将其传递给映射器的方法,然后该方法从所述对象检索信息并将其发送到存储器或从存储器检索数据并将其应用到该域对象。
User
实例不关心它是否保存。 它对域逻辑没有影响。
上一篇: Implementing Domain Model and Data Mapper pattern with external data sources