策略模式
-
定义:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
-
优点:(1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。(2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
-
缺点:(1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。(2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。
-
博客:https://blog.csdn.net/hanchao5272/article/details/96480255、https://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html
-
实例:购物车支付策略场景:每个商品都有名称和价钱。购物车可以添加多个商品。购物车支付方式暂时只支持支付宝和微信,但是后期可能会增减更多支付方式。
-
类图:
-
代码:
/**
* 商品类
*/
public class Goods {
private String name;
private Double price;
public Goods(String name, Double price) {
this.name = name;
this.price = price;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(Double price) {
this.price = price;
}
public String getName() {
return name;
}
public Double getPrice() {
return price;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
/**
* 支付策略接口
*/
public interface PayStrategy {
/**
* 支付
*
* @param cost
*/
void pay(Double cost);
}
/**
* 具体支付策略 - 支付宝
*/
public class AliPayStrategy implements PayStrategy {
@Override
public void pay(Double cost) {
System.out.println("使用支付宝支付了 " + cost + " 元");
}
}
/**
* 具体支付策略 - 银联
*/
public class UnionPayStrategy implements PayStrategy {
@Override
public void pay(Double cost) {
System.out.println("使用银联支付了 " + cost + "元");
}
}
/**
* 具体支付策略 - 微信
*/
public class WechatPayStrategy implements PayStrategy {
@Override
public void pay(Double cost) {
System.out.println("使用微信支付了 " + cost + " 元");
}
}
/**
* @author wmy
* @date 2021/8/11 17:16
*/
/**
* 购物车
*/
public class StrategyShoppingCart {
/**
* 商品列表
*/
private List<Goods> goodsList;
/**
* 支付策略
*/
private PayStrategy payStrategy;
public StrategyShoppingCart() {
this.goodsList = new ArrayList<>();
}
/**
* 添加商品
*
* @param goods
*/
public void addGoods(Goods goods) {
this.goodsList.add(goods);
}
/**
* 计算总价
*
* @return
*/
public Double calcCost() {
Double totalCost = 0.0;
for (Goods goods : this.goodsList) {
totalCost += goods.getPrice();
}
return totalCost;
}
/**
* 选择支付策略
*
* @param payStrategy
*/
public void setPayStrategy(PayStrategy payStrategy) {
this.payStrategy = payStrategy;
}
/**
* 支付
*/
public void pay() {
this.payStrategy.pay(this.calcCost());
}
}
/**
* 测试策略模式
*/
public class TestStrategy {
public static void main(String[] args) {
//支付宝支付
StrategyShoppingCart strategyShoppingCart1 = new StrategyShoppingCart();
strategyShoppingCart1.addGoods(new Goods("一箱牛奶", 34.55));
strategyShoppingCart1.addGoods(new Goods("一瓶白酒", 250.50));
strategyShoppingCart1.setPayStrategy(new AliPayStrategy());
strategyShoppingCart1.pay();
//银联支付
StrategyShoppingCart strategyShoppingCart2 = new StrategyShoppingCart();
strategyShoppingCart2.addGoods(new Goods("一箱牛奶", 34.55));
strategyShoppingCart2.addGoods(new Goods("一瓶啤酒", 3.50));
strategyShoppingCart2.setPayStrategy(new UnionPayStrategy());
strategyShoppingCart2.pay();
}
}