【发布时间】:2022-01-10 21:32:50
【问题描述】:
我要解决两个问题:
- 在现有方法之间共享数据
- 减少对这些方法的耦合
我可以使用什么模式来计算总数?
/** @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