当前位置 博文首页 > 韩超的博客 (hanchao5272):设计模式-策略模式-以购物车的支付策
超级链接: Java常用设计模式的实例学习系列-绪论
参考:《HeadFirst设计模式》
策略模式是一种行为
模式。
策略模式:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
如果某种行为拥有多种运作方式,那么把这种行为视为一种策略,把这些运作方式视为策略实现,这些策略实现之间可以相互替换。
这样,行为调用方就可以在运行时,根据不同的需求,将相应的策略实现当做参数,以达到行为按照某种方式运作的目的。
本文以购物车的支付策略
为场景来学习策略模式
:
由于本文的关注对象是设计模式,所以这里直接列出商品的代码。
商品:Goods
/**
* <p>商品</P>
*
* @author hanchao
*/
@Setter
@Getter
@AllArgsConstructor
public class Goods {
/**
* 商品名称
*/
private String name;
/**
* 商品价格
*/
private Float price;
}
购物车:OrdinaryShoppingCart
/**
* <p>购物车(普通版本)</P>
*
* @author hanchao
*/
@Slf4j
public class OrdinaryShoppingCart {
/**
* 商品列表
*/
private List<Goods> goodsList;
public OrdinaryShoppingCart() {
goodsList = new ArrayList<>();
}
/**
* 添加商品
*/
public OrdinaryShoppingCart addGoods(Goods goods) {
goodsList.add(goods);
return this;
}
/**
* 计算总价
*/
public float totalCost() {
return goodsList.stream().map(Goods::getPrice).reduce(Float::sum).orElse(0f);
}
/**
* 通过支付宝支付
*/
public void payWithAlipay() {
log.info("通过支付宝支付了" + totalCost() + "元.");
}
/**
* 通过微信支付
*/
public void payWithWeChat() {
log.info("通过微信支付了" + totalCost() + "元.");
}
}
测试代码:ShoppingCartDemo
/**
* <p>购物车场景测试</P>
*
* @author hanchao
*/
public class ShoppingCartDemo {
public static void main(String[] args) {
//购物车(普通版本)
//张三的购物行为
new OrdinaryShoppingCart()
.addGoods(new Goods("一箱牛奶", 34.55f))
.addGoods(new Goods("一瓶白酒", 250.50f))
.payWithAlipay();
//李四的购物行为
new OrdinaryShoppingCart()
.addGoods(new Goods("一箱牛奶", 34.55f))
.addGoods(new Goods("一瓶啤酒", 3.50f))
.payWithWeChat();
}
}
运行结果:
2019-07-02 15:53:48,424 INFO [main-1] pers.hanchao.designpattern.strategy.ordinary.OrdinaryShoppingCart:44 - 通过支付宝支付了285.05元.
2019-07-02 15:53:48,429 INFO [main-1] pers.hanchao.designpattern.strategy.ordinary.OrdinaryShoppingCart:51 - 通过微信支付了38.05元.
优点:
实现简单
:代码逻辑很简单,并且只需要编写一个类即可。缺点:
扩展性差
,每增减一种支付方式,都需要修改OrdinaryShoppingCart
,违背了设计模式的开放-封闭原则(OCP,对扩展开放,对修改关闭)。可复用低
,每种支付方式都采用不同的方法命名。策略模式
的关键在于:将行为及其运作方式抽象为策略和策略实现。对于本场景而言,
支付
就是一种行为,可以将其视为一种策略,即:支付策略。支付宝支付
和微信支付
都是支付
行为的不同运作方式,可以分别将其视为一种策略实现。支付策略:PayStrategy
/**
* <p>支付策略</P>
*
* @author hanchao
*/
public interface PayStrategy {
/**
* 支付
*
* @param cost 支付金额
*/
void pay(Float cost);
}
支付策略实现一:支付宝
/**
* <p>支付宝支付策略</P>
*
* @author hanchao
*/
@Slf4j
public class AliPayStrategy implements PayStrategy {
@Override
public void pay(Float cost) {
log.info("通过支付宝支付了" + cost + "元.");
}
}
支付策略实现二:微信
/**
* <p>微信支付策略</P>
*
* @author hanchao
*/
@Slf4j
public class WeChatPayStrategy implements PayStrategy {
@Override
public void pay(Float cost) {
log.info("通过微信支付了" + cost + "元.");
}
}
购物车(策略模式版本):StrategyShoppingCart
/**
* <p>购物车(策略模式版本)</P>
*
* @author hanchao
*/
@Slf4j
public class StrategyShoppingCart {
/**
* 商品列表
*/
private List<Goods> goodsList;
/**
* 支付策略
*/
private PayStrategy payStrategy;
public StrategyShoppingCart() {
goodsList = new ArrayList<>();
}
/**
* 添加商品
*/
public StrategyShoppingCart addGoods(Goods goods) {
goodsList.add(goods);
return this;
}
/**
* 计算总价
*/
public float totalCost() {
return goodsList.stream().map(Goods::getPrice).reduce(Float::sum).orElse(0f);
}
/**
* 选择支付策略
*/
public StrategyShoppingCart setPayStrategy(PayStrategy payStrategy) {
this.payStrategy = payStrategy;
return this;
}
/**
* 支付
*/
public void pay() {
if (Objects.isNull(payStrategy)) {
throw new IllegalStateException("未选择支付策略");
} else {
payStrategy.pay(totalCost());
}
}
}
策略(抽象类/接口)PayStrategy
作为客户端StrategyShoppingCart
的成员变量,如此才能承载不同的策略实现。setPayStrategy(PayStrategy payStrategy)
,为策略实现的切换提供入口。测试代码:ShoppingCartDemo
/**
* <p>购物车场景测试</P>
*
* @author hanchao
*/
public class ShoppingCartDemo {
public static void main(String[] args) {
//购物车(策略模式版本)
//王五的购物行为
new StrategyShoppingCart()
.addGoods(new Goods("一箱牛奶", 34.55f))
.addGoods(new Goods("一瓶白酒", 250.50f))
.setPayStrategy(new AliPayStrategy()).pay();
//赵六的购物行为
new StrategyShoppingCart()
.addGoods(new Goods("一箱牛奶", 34.55f))
.addGoods(new Goods("一瓶啤酒", 3.50f))
.setPayStrategy(new WeChatPayStrategy()).pay();
}
}
运行结果:
2019-07-02 17:47:07,309 INFO [main-1] pers.hanchao.designpattern.strategy.strategy.strategy.impl.AliPayStrategy:15 - 通过支付宝支付了285.05元.
2019-07-02 17:47:07,310 INFO [main-1] pers.hanchao.designpattern.strategy.strategy.strategy.impl.WeChatPayStrategy:15