【发布时间】:2017-07-05 08:35:16
【问题描述】:
我正在开发一个遵循 OOP 和 DDD 的 php 购物车。 我有一个 ShoppingCart 类作为不同类型的 CartItem 实例(Type1ProductItem、Type2ProductItem 等)的集合,它们都实现了 CartItemInterface。
管理要用作 ShoppingCart 内部集合中的键的唯一标识符的最佳方法是什么?
我当前的解决方案是 CartItemInterface 中的“getPrimaryKey()”方法返回基于类型和 id 的唯一标识符:
购物车:
public function add(CartItemInterface $CartItem) {
$this->items[$CartItem->getPrimaryKey()] = $CartItem;
}
public function remove(CartItemInterface $CartItem) {
unset($this->items[$CartItem->getPrimaryKey()]);
}
导致:
ShoppingCart->add($CartItem);
ShoppingCart->doSomething($CartItem);
但是通过这种方式,我必须在购物车上的每个操作(添加、删除、更新..)之前创建一个 CartItem,具体取决于 uri 的参数,然后将其传递给 ShoppingCart 的相关方法:
// type and id coming as parameters
switch ($type) {
case 1 : $CartItem = new Type1ProductItem($id); break;
case 2 : $CartItem = new Type2ProductItem($id); break;
....
}
ShoppingCart->doSomething($CartItem);
这不是一个大问题,因为我可以使用工厂来避免重复的逻辑,但如果唯一标识符 (UID) 在 CartItem 实例之外创建并在第一次项目时传递给 ShoppingCart 是否会是一个更可行的解决方案添加了吗?
ShoppingCart->add($UID, CartItemInterface $CartItem);
ShoppingCart->doSomething($UID); // no need of CartItem instance here
我不确定在 CartItem 实例之外管理 uid 是否好。 你怎么看? 解决方案的优缺点是什么? 非常感谢。
【问题讨论】:
-
将
$UID传递给工厂。它应该使用它来初始化它创建的CartItemInterface对象的PK字段。不要修改ShoppingCart的接口。 -
为什么需要将
CartItemInterface传递给add?为什么不传递所需的属性,如 productId、productType、数量和价格? -
我认为您不需要 shoppingCart 类中的 cartItem 主键。为什么不简单地做 $this->items[] = $CartItem;我认为 cartItem 应该是一个值对象,因为它只是一个项目的描述,而不是项目本身。所以它并不需要一个 id
-
@ConstantinGALBENU 我需要 CartItem 中的一些行为,属性数组或值对象是不够的。
-
@MohamedBouallegue 我需要 CartItem 中的一些行为,因此值对象是不够的。关于
$this->items[] = $CartItem,我同意它会更快,但这样我每次需要识别一个项目时都必须循环遍历项目集合,没有主键..或者我错过了什么?
标签: php oop domain-driven-design