在将数据作为API调用的输出发送之前,我一直在使用变换器(分形)来转换数据。 所以从控制器我调用变换器类并传递像这样的数据
$data = $this
->myModelClass
->search($filters);
$data = $this
->listTransformer
->transform($data);
并在变压器中,
public function transform($result)
{
$resource = $this->factory->make($result, function ($item) {
return [
'id' => $item->id,
'name' => $item->name,
'category_name' => $this->anotherModel->getCategory($item->category_id),
'revenue' => $this->anotherModel->getRevenue($item->earnings)
];
});
$result = $this
->manager
->createData($resource)
->toArray();
return $result['data'];
}
所以基本上,我从变压器调用模型。这是正确的做法吗?
我见过另一种使用包含的方法,但如果我在数组中有多个项目, 需要传递给模型以获取细节,我需要编写一些变换器。
答案 0 :(得分:1)
一般来说,这是一种不好的做法,因为它违反了"单一责任" SOLID原理。您的变压器不再仅仅负责转换数据,现在它还会查询数据,然后将数据绑定到您的数据层,使其紧密耦合"。
将模型对象传递给包含其他相关模型的变换器是没有坏处的,但是变换器应该有一个责任,即转换数据。
通常我会为每个模型创建一个变换器,然后让域(聚合)模型使用其他显式变换器,这将涉及您构建一个"域" (聚合)模型之前将其传递给变压器。这意味着对数据层的任何更改都会对变换器产生最小的影响。
以下工作示例:
class LeadTransformer extends Transformer implements LeadTransformerInterface {
/**
* @var CustomerTransformerInterface
*/
protected $customerTransformer;
/**
* @var EnquiryTypeTransformerInterface
*/
protected $enquiryTypeTransformer;
/**
* @var PlanTransformerInterface
*/
protected $planTransformer;
/**
* @param CustomerTransformerInterface $customerTransformer
* @param EnquiryTypeTransformerInterface $enquiryTypeTransformer
* @param PlanTransformerInterface $planTransformer
*/
public function __construct(CustomerTransformerInterface $customerTransformer, EnquiryTypeTransformerInterface $enquiryTypeTransformer, PlanTransformerInterface $planTransformer)
{
$this->customerTransformer = $customerTransformer;
$this->enquiryTypeTransformer = $enquiryTypeTransformer;
$this->planTransformer = $planTransformer;
}
/**
* Transforms a lead
*
* @param array $lead
* @return array
*/
public function transform($lead)
{
$data = [
// Do Transformation
];
if($lead->enquiry_type)
{
$data['enquiry_type'] = $this->enquiryTypeTransformer->transform($lead->enquiry_type);
}
if($lead->customer)
{
$data['customer'] = $this->customerTransformer->transform($lead->customer);
}
if($lead->plan)
{
$data['plan'] = $this->planTransformer->transform($lead->plan);
}
return $data;
}
}
在上面的例子中,LeadTransformer有三个其他变换器被laravel的IoC Container注入为依赖。在转换相关模型中的数据时,使用了模型转换器。
这意味着我是否需要操纵"客户"模型,我没有必要干涉我的应用程序的其他方面,因为它都被抽象出来。
希望这能回答您的问题,如果您有任何后续问题请发表评论,我会尽力解决这些问题