我有一个REST API。我需要创建演示文稿(DTO)对象,但此对象的构造取决于请求 - 它的差异为15%。 我想知道我应该使用什么模式。
我的情况:
//presentation-DTO
class Item {
private $name;
private $price;
private $tags;
private $liked; //is Liked by logged user
...
public function __construct(Item $item, bool $liked, ...)
{
$this->name = $item->getName();
$this->price = $item->getPrice();
$this->tags = $item->getTags();
$this->liked = $liked;
...
}
}
当用户未登录时 - 我不需要$ likes
显示项目列表时 - 我不需要$ tag
还有更多属性如上所述。
我的第一个想法是使用Builder原理。
$itemBuilder = new ItemBuilder();
$itemBuilder->setItem($item);
...
if($user) {
$itemBuilder->setUserLiked($userLiked);
...
}
return $itemBuilder->build();
它解决了构造函数中包含太多参数的问题。
但是,我还不需要构建所有参数 - 例如。我不需要标签(在列表中)。当我使用延迟加载时,我不希望我的dto构造函数调用它们。
所以我想,也许工厂..但是我的问题是太多(和可选)参数正在返回。
你将如何解决这个问题?
答案 0 :(得分:0)
抱歉,我没有必要的评论作出回答。
你想用Item
课做什么?您的课程为Item
,第一个参数的类型为Item
。我无法想象它的运作方式。
我希望保持业务登录以在单独的类中设置适当的属性:
/**
* A class for business logic to set the proper properties
*/
class ItemProperties {
private $item;
public $isLogin = false;
public $showList = false;
.....
public function __construct(Item &$item) {
// set all properties;
}
public function getProperties() {
$retVal = [];
if($this->isLogin == true) {
$retVal['liked'] = true;
}
if($this->showList == true) {
$retVal['tags'] = $this->item->getTags();
}
if(....) {
$retVal['...'] = $this->item->.....();
}
return $retVal;
}
}
/**
* DTO
*/
class Item {
public function __construct(ItemProperties $itemProps) {
$this->setItemProps($itemProps);
}
// If you prefer lazy loading here...maybe make it public
// and remove call from constructor.
private function setItemProps(&$itemProps) {
$properties = $itemProps->getProperties();
foreach($properties AS $propName => $propValue) {
$this->$propName = $propValue;
}
}
}
// Usage:
$itemProps = new ItemProperties($Item);
// set other properties if you need to...
$itemProps->isLogin = false;
$item = new Item($itemProps);