策略模式UML类图
一、策略接口
首先、定义一个策略接口,这里我定义了一个支付的策略
import java.math.BigDecimal;
/**
* 支付策略
*/
public interface PayStrategy {
//支付类型
String paySource();
//支付
void pay(BigDecimal amount);
}
二、具体策略实现类
然后,创建实现策略接口的具体策略类,这里我定义了三种策略:支付宝、微信和银联
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
/**
* 支付宝
*/
@Component
public class AlipayPayStrategy implements PayStrategy {
@Override
public String paySource() {
return "AlipayPay";
}
@Override
public void pay(BigDecimal amount) {
System.out.println("支付宝支付-金额:"+amount);
}
}
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
/**
* 微信支付
*/
@Component
public class WeChatPayStrategy implements PayStrategy{
@Override
public String paySource() {
return "WeChatPay";
}
@Override
public void pay(BigDecimal amount) {
System.out.println("微信支付-金额:"+amount);
}
}
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
/**
* 银联支付
*/
@Component
public class UnionPayStrategy implements PayStrategy{
@Override
public String paySource() {
return "UnionPay";
}
@Override
public void pay(BigDecimal amount) {
System.out.println("银联支付-金额:"+amount);
}
}
三、策略实现的上下文
接下来,我们创建一个上下文类,它将根据客户端的需求选择合适的策略
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class PayStrategyContext {
private Map<String, PayStrategy> payStrategyMap;
public PayStrategyContext() {
this.payStrategyMap = new HashMap<>();
}
@Autowired
public void setPayStrategyMap(List<PayStrategy> list) {
if (list == null || list.isEmpty()) {
throw new RuntimeException("PayStrategy List is empty");
}
payStrategyMap = list.stream().collect(Collectors.toMap(item -> item.paySource(), item -> item, (v1, v2) -> v1));
}
public PayStrategy getPayStratrgy(String paySource) {
PayStrategy payStrategy = payStrategyMap.get(paySource);
return payStrategy;
}
}
四、调用策略
//支付策略的环境类,需要通过他实现该调用那个策略
@Autowired
private PayStrategyContext payStrategyContext;
@Test
public void getPayStrategy(){
//策略模式
String alipayPay = "AlipayPay";//支付宝支付
PayStrategy alipayPayStrategy = payStrategyContext.getPayStratrgy(alipayPay);
alipayPayStrategy.pay(new BigDecimal("11.56"));
String weChatPay = "WeChatPay";//微信支付
PayStrategy weChatPayStrategy = payStrategyContext.getPayStratrgy(weChatPay);
weChatPayStrategy.pay(new BigDecimal("21.56"));
String unionPay = "UnionPay";//银联支付
PayStrategy unionPayStrategy = payStrategyContext.getPayStratrgy(unionPay);
unionPayStrategy.pay(new BigDecimal("31.56"));
}
五、策略模式的优点和缺点
策略模式的优点包括:
- 开闭原则:策略模式提供了对开闭原则的支持,可以在不修改原有系统的基础上,选择不同的行为,也可以额外扩展其它行为。
- 避免代码冗余:可以避免使用多重条件判定语句,可以避免出现大量的if…else…语句,switch语句等。
- 提高了代码的灵活性和可维护性。
策略模式的缺点包括:
- 策略类的数量可能会很多,这会给客户端调用带来一定的困难。
- 如果策略类之间存在相互依赖关系,那么设计起来就比较困难。