【问题标题】:Design pattern for share calculating order totals份额计算订单总额的设计模式
【发布时间】:2022-01-10 21:32:50
【问题描述】:

我要解决两个问题:

  1. 在现有方法之间共享数据
  2. 减少对这些方法的耦合

我可以使用什么模式来计算总数?

/** @var array $orderData */

// Ordered products total price
$orderedProductsTotal = $this->orderedProductsTotalPrice($orderData);

$total = $orderedProductsTotal;

// Shipping cost dependent on ordered products total price
$shippingCost = $this->shippingCost($orderedProductsTotal);
$total += $shippingCost;

// Client allowed credit, depends on ordered products total price
$total -= $this->credit($orderedProductsTotal);

// Available coupon depends on order data (i.e. special products in order, etc)
$total -= $this->coupon($orderData);

// Client personal discount applying on total amount, excluding shipping cost
$total -= $this->personalDiscount($total - $shippingCost);

我在想这样的事情

$calcs = [
    'OrderProductsCalc',
    'ShippingCalc',
    'CreaditCalc',
    'CouponCalc',
    'PersonalDiscountCalc',
];

$total = 0;


foreach ($calcs as $v) {
    // How to share data between calculators?
    // Separated calculated total values of each calculator
    // Order data
    // Something else
    /** @var CalculatorInterface $calculator */
    $calculator = $this->container->get($v);
    $total = $calculator->getTotal($total);
}

这是一个依赖于购物车项目的简单类

class OrderProductsCalc implements CalcInterface
{
    private Cart $cart;

    public function __construct(Cart $cart)
    {
        $this->cart = $cart;
    }

    public function getTotal(float $total): float
    {
        $subTotal = $this->cart->getTotal();

        return $total + $subTotal;
    }
}

ShippingCalc 也很简单,因为它在OrderProductsCalc 旁边运行。

但是CreaditCalc::getTotal() 应该接收来自OrderProductsCalc::getTotal()$subTotal 内部值$total

class CreaditCalc implements CalcInterface
{
    private $customer;

    public function __construct(Customer $customer)
    {
        $this->customer = $customer;
    }

    /**
     * @var float $total The $subTotal inner value from OrderProductsCalc::getTotal()
     */
    public function getTotal(float $total): float
    {
        $balance = $this->customer->getBalance();
        if ($balance) {
            $credit = min($balance, $total);
            
            if ($credit > 0) {
                $total -= $credit;
            }
        }
        
        return $total;
    }
}

【问题讨论】:

    标签: php design-patterns architecture


    【解决方案1】:

    `您可以利用命令模式稍微修改设计。 您可以为 'OrderProductsCalc', '运费计算', '信用计算器', '优惠券计算器', '个人折扣计算'

    现在您可以通过“链接命令”来进行总体计算以进行通用设计。 根据计算创建具有相应命令的链。 将一个命令的输出传递给下一个命令。 在抽象服务类中编写命令链接的逻辑。 根据不同的计算创建子类 伪代码,类似于java中的(解释意图)。

    abstract class Service{
    
    constructor(commands){
        this.commands = commands
    }
    
    Command[] commands;
    
    public final executeChain(){
        loop(command in commands){
            command.execute();
        }
        perform();
    }
    abstract protected void perform();
    

    }

    class CalculateTotal extends Service{
    protected void perform(){
    //specific
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2017-03-14
      • 2021-11-23
      • 2019-07-29
      • 2023-04-07
      • 2018-12-01
      • 1970-01-01
      相关资源
      最近更新 更多