求大神帮忙看看这个结构设计是否有问题: [ 2.0 版本 ]
先介绍业务场景:
销售型业务,售卖材料的。比如,地砖,地板,油漆,等等
但是公司卖这些东西的价格会有不同,例如遇到节假日会打折,满多少钱会打折。买了数量多优惠等等。
我首先想到了是策略模式
自己硬着头皮设计了一个结构,希望大牛帮帮忙看看这么设计的行吗?
首先,文件结构如下图:
![2220A889-E3B4-4DCD-96E2-4FA126497F8E.png](/uploads/images/201711/10115339566.png "2220A889-E3B4-4DCD-96E2-4FA126497F8E.png")
源码目录:
https://github.com/CoderShawnZhang/Strategy
大神下来看看可以吗?
调用:
//$dizhuan = new Dizhuan();
$diban = new Diban();
$priceStractegy = new FivezhePrice();//五折计价
$dimian = new Dimian($diban,$priceStractegy);
$dimian->getPrice();
共 2 个回答
-
哪能一个产品就声明一个类?说一下我的方法:订单总金额由物品金额和服务金额两部分组成。你说的“满减”、“节假日优惠”等都可以算进服务。假设地砖的价格是 5元/块,明天就是双十一了,你想搞个促销——消费满 500 元减50元。你可以新建一个服务,该服务的计费逻辑是看物品金额是否大于等于 500,是则新建一条金额为 -50 的服务记录。
假设客人买了 100 块, 付款金额 = 5x100 (物品金额)-50 (服务金额)= 450. 说得有些笼统,我之前做过一个类似的项目,如果你有兴趣,可以详细讨论。
共 1 条回复灰太狼 觉得很赞 -
<?php // 促销抽象类 (Component: 组件对象接口) abstract class Promotion { public $price; // 统计优惠价格 // 计算价格 abstract public function calePrice(); } // 原始订单 (ConcreteComponent: 具体的组件对象, 实现了组件接口, 被装饰器装饰的原始对象) class Order extends Promotion { public $goodsInfo; public function __construct ($goodsInfo) { $this->goodsInfo = $goodsInfo; } public function calePrice() { // 计算商品价格 foreach($this->goodsInfo as $key=>$val) { $this->price += $val['price']; } return $this->price; } } // 装饰器: 父类 (Decorator: 所有装饰器的父类, 需要定义一个与组件接口一致的接口) class Decorator extends Promotion { public $promotion; public $goodsInfo; public function __construct(Promotion $promotion) { $this->promotion = $promotion; $this->goodsInfo = $promotion->goodsInfo; } public function calePrice(){ } } // 装饰器: 代金券 (ConcreteDecorator: 具体的装饰器类) class CashCoupon extends Decorator { public function calePrice() { foreach($this->goodsInfo as $key=>$val) { if($val['couponType'] == 1) { $this->price += $val['couponVal']; } } return $this->promotion->calePrice() - $this->price; } } // 装饰器: 打折券 (ConcreteDecorator: 具体的装饰器类) class DiscountCoupon extends Decorator { public function calePrice(){ foreach($this->goodsInfo as $key=>$val) { if($val['couponType'] == 2) { $this->price += $val['price'] * (1 - $val['couponVal']); } } return $this->promotion->calePrice() - $this->price; } } // 装饰器: 免单券 (ConcreteDecorator: 具体的装饰器类) class FreeCoupon extends Decorator { public function calePrice(){ foreach($this->goodsInfo as $key=>$val) { if($val['couponType'] == 3) { $this->price += $val['price']; } } return $this->promotion->calePrice() - $this->price; } } // 装饰器: 满减 (ConcreteDecorator: 具体的装饰器类) class MoneyOff extends Decorator { // 满减规则, atLeastAmount: 满减金额, amountOff: 减免金额/优惠金额 private $moneyOffRules = [ ['atLeastAmount'=> 1000, 'amountOff'=> 10, 'start'=>0, 'end'=>1000], ['atLeastAmount'=> 2000, 'amountOff'=> 20, 'start'=>1000, 'end'=>2000], ['atLeastAmount'=> 3000, 'amountOff'=> 30, 'start'=>2000, 'end'=>3000], ['atLeastAmount'=> 4000, 'amountOff'=> 40, 'start'=>3000, 'end'=>4000], ]; public function calePrice() { $price = $this->promotion->calePrice(); foreach($this->moneyOffRules as $key=>$val) { if($price >= $val['start'] and $price < $val['end']) { $this->price = $val['amountOff']; } } return $price - $this->price; } } // couponType: 优惠券类型( 1-代金券, 2-折扣券, 3-免单券) // couponVal : 优惠金额或折扣 $goodsInfo = [ ['id'=>1, 'goodsName'=>'商品01', 'price'=>1000, 'couponType'=>1, 'couponVal'=>100], ['id'=>2, 'goodsName'=>'商品02', 'price'=>1000, 'couponType'=>2, 'couponVal'=>0.5], ['id'=>3, 'goodsName'=>'商品03', 'price'=>1000, 'couponType'=>3, 'couponVal'=>0], ['id'=>4, 'goodsName'=>'商品04', 'price'=>1000, 'couponType'=>0, 'couponVal'=>0], ['id'=>5, 'goodsName'=>'商品05', 'price'=>1000, 'couponType'=>2, 'couponVal'=>0.6], ]; $order = new Order($goodsInfo); // 5000 $order = new CashCoupon($order); // 使用优惠方式: 代金券 4900 $order = new DiscountCoupon($order); // 使用优惠方式: 打折券 4000 $order = new FreeCoupon($order); // 使用优惠方式: 免单券 3000 $order = new MoneyOff($order); // 使用优惠方式: 满减 2960 echo $order->calePrice(); // 3000
灰太狼
注册时间:2016-11-19
最后登录:2023-07-14
在线时长:76小时17分
最后登录:2023-07-14
在线时长:76小时17分
- 粉丝28
- 金钱3290
- 威望150
- 积分5550