根据多个参数创建不同的对象

时间:2017-03-17 11:12:05

标签: oop design-patterns

我有一个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构造函数调用它们。

所以我想,也许工厂..但是我的问题是太多(和可选)参数正在返回。

你将如何解决这个问题?

1 个答案:

答案 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);