3

我希望实现一些电子商务功能,在达到一定数量时提供折扣。问题是,它不是一个 sku 的数量,一个类别中的任何数量的其他产品在总计达到阈值时都会触发数量中断。

因此,如果我有一个 Cart_Product 的模型类,可以说,我通常会将获取该类中价格的逻辑作为一种方法。但是由于需要考虑当前购物车中该类的其他实例,因此我不确定继续进行的最佳方法。

我是否在 Cart_Product get_price 方法中调用“所有者”购物车实例,然后添加逻辑以检查数量中断?或者在这一步是否有更好的设计模式可以使用?

4

3 回答 3

1

您描述的逻辑是购物车范围的功能;由于购物车是内部产品的逻辑所有者,因此您可以在那里实现它:

class Cart
{
    private $products; // Cart_Product[]

    // ...

    function calculateDiscount()
    {
        $totalQuantity = array_reduce($this->products, function($sum, $product) {
            return $sum + $product->getQuantity();
        }, 0);

        if ($totalQuantity > 10) {
            $this->cartDiscount = 25; // apply 25% discount on the cart
        } else {
            $this->cartDiscount = 0;
        }
    }
}

这为全球购物车折扣引入了一个单独的实体。如果您不希望这样,则必须将折扣应用于每个单独的项目。

于 2013-08-02T02:33:28.187 回答
1

首先,模型不是类或实例。模型是一层。您在问题中所说的实际上是域对象(假设它们也不负责保存自己,这将违反SRP

至于应用折扣,取决于您购物车中的每个产品是否有单独的折扣,所有产品的折扣都是相同的:

  • 如果每个产品都可以有单独的折扣,那么其逻辑应该驻留在Product域对象中。

  • 如果所有产品都获得相同的折扣,那么折扣应该只影响总和,因此 - 在Cart实例中计算。

于 2013-08-01T19:58:21.743 回答
0

我刚刚经历了一些非常相似的事情。实际上,购物车唯一应该知道的是产品 ID 和数量。其他一切都应仅用于展示目的。换句话说,产品对象始终对价格负责。将价格存储在购物车中的唯一原因是帮助在视图中显示它。否则,我们假设始终必须通过任何插入或更新检查价格,以防止欺诈。

这是另一种情况 - 你有一个特殊的运输,比如购买价值 100 美元的合格商品,你可以获得免费送货。特定产品可能有单独的运输特惠。计算的唯一方法是使用所有购物车项目。

所以我的解决方案 - 我不确定这是最佳的 - 是将购物车物品传递给运输对象 - 进行运输计算 - 可选择添加特定产品的消息以显示在购物车中 - 然后返回购物车物品。

否则,您必须将运输方法放在购物车类中,这没有任何意义,但也许还有另一种方法可以做到这一点。

这是另一种情况 - 库存控制。有人订购了 30 个蓝色小部件,但您只有 10 个蓝色小部件。好的,您可以在将商品插入购物车时检查库存。但是如果他们更新购物车然后增加到 30 呢?这意味着我们必须在每次更新购物车时检查库存 - 对于购物车中的每件商品。如果我们这样做,那么最好在价格上涨或下跌的情况下获得价格。

所以我拿走购物车物品 - 并将它们传递给产品对象 - 检查库存 - 如有必要,将物品的数量减少到当前库存 - 可选地添加解释库存有限的消息 - 然后传递回购物车对象。

最后 - 建议您拥有一个拥有购物会话的对象。然后就是总数。这样,购物车永远不会负责总计 - 它只是一个容器。一种方法是您只需开始一个订单,然后将不同的总数存储在那里。

于 2013-08-18T21:49:42.107 回答