策略模式和工厂模式在促销系统下的应用
设计模式为我们提供了在某些应用场景下特定问题的解决方案,今天我们利用策略模式和工厂模式实现一个简单的促销系统。
实现语言:PHP
我们先来回顾一下策略模式和工厂模式的基本知识
策略模式
Gof 对策略模式的作用的说明如下
定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替换。本模式使得算法可独立于他的客户而变化。
策略模式对算法进行抽象,使得类可以方便地实现不同的算法,而调用他的客户端完全感觉不出来。
工厂模式
Gof 整理的工厂模式主要有抽象工厂模式和工厂方法模式,大家还经常提到一种简单工厂模式,工厂模式将类的创建进行封装,使得类的创建和使用可以相互分离,独立变化。
问题系统描述
要实现一个促销系统,实现对单件产品和购物车产品集合的促销。针对单件产品,促销策略有降价、打折、赠品,限制条件有无条件限制、商品满足一定价格;针对购物车产品集合,促销策略有打折、降价、赠品、低价免单、免邮,限制条件有无条件限制、商品集合总价满一定价格、商品集合满一定数量。
基本数据表及类设计
促销系统核心数据表设计
- promotion表,存储信息包括促销类别(针对单件产品的促销活动还是针对产品集合的促销活动),优惠策略,限制条件。
促销系统核心类设计
- Promotion 类,对应promotion数据表,实现某个限制条件下针对单件产品或产品集合的某个促销策略。
- Benefit 系列类,提供在产品和产品集合上不同的促销优惠的算法。
- Checkout 系列类,提供在产品和产品集合上不同的限制条件的算法。
除了以上核心类类外,还有以下基础类,比如Product(产品类,实现一件产品的具体功能)、Collection(集合类,某些类对象的集合,可以继承Collection实现比如产品集合等具体集合类)。
促销系统设计思路
通过以上分析,我们知道实现促销的对象有两个:单件产品和产品集合;主要功能也有两个:判断是否满足限制条件和实现某种促销优惠。限制条件和促销优惠这两个功能具有稳定性,具体实现算法具有可变性。这样我们可以针对限制条件和促销优惠抽象出来其接口,使用策略模式进行封装,使得判断条件和促销优惠的算法可以独立于客户端进行变化和增减,并通过工厂模式创建具体算法实例。我们还应该设计针对 Promotion 类接口,抽象出来提供给客户端调用算法的方法。
促销系统实现
接口设计
interface Promotion
{
/*
* Promotion 类的接口,标注 Promotion 类向系统提供的具体功能
*/
//返回促销策略的类别信息
public function getBenefit();
//返回促销策略的值
public function getBenefitValue();
//返回限制条件的信息
public function getLimit();
//返回限制条件的值
public function getLimitValue();
//创建此次促销产生的优惠信息的对象
public function makeBenefit($attribute);
//判断某个产品集合是否满足促狭的限制条件
public function itemsCheckout(Collection $items, $limitValue);
//判断某个产品是否满足促销的限制条件
public function productCheckout(Product $product, $limitValue);
//针对某个产品集合计算促销策略
public function itemsPromotionCalculate(Collection $items);
//针对某个产品计算促销策略
public function productPromotionCalculate(Product $product);
}
interface PromotionBenefit{
/*
* 促销优惠策略的接口,提供针对产品集合和单件产品的促销优惠的方法
*/
// 计算产品集合的促销优惠
public function itemsPromotionCalculate(Promotion $promotion, Collection $items);
// 计算单件产品的促销优惠
public function productPromotionCalculate(Promotion $promotion, Product $product);
}
interface PromotionCheckout{
/*
* 促销限制条件的接口,提供针对产品集合和单件产品的判断限制条件方法
*/
//判断产品集合的限制条件
public function itemsCheckout(Collection $items, $limitValue);
//判断单件产品的限制条件
public function productCheckout(Product $product, $limitValue);
}
限制条件策略的实现
根据上面的限制条件策略的接口,接下来我们来实现无限制条件、满一定价格、满一定数目这些限制条件的策略
/*
* 实现无条件限制策略,因为无条件限制,所以接口的两个方法均直接返回true
*/
class CheckoutNone implements PromotionCheckout{
public function itemsCheckout(Collection $items, $limitValue)
{
return true;
}
public function productCheckout(Product $product, $limitValue)
{
return true;
}
}
/*
* 实现对单件商品和商品集合