你还在写满屏的 if/ else/ switch 之类的判断逻辑吗?
博主在开发人员的代码中看过太多这样的低级代码了,真的太 low,极不好维护,本文博主就教你如何用策略模式干掉 if/ else/ switch,让你的代码更优雅。
什么是策略模式?
比如说对象的某个行为,在不同场景中有不同的实现方式,这样就可以将这些实现方式定义成一组策略,每个实现类对应一个策略,在不同的场景就使用不同的实现类,并且可以自由切换策略。
策略模式需要一个策略接口,不同的策略实现不同的实现类,在具体业务环境中仅持有该策略接口,根据不同的场景使用不同的实现类即可。
策略模式实战
举个实际的例子,某公司是做支付的,根据不同的客户类型会有不同的支付方式和支付产品,比如:信用卡、本地支付,而本地支付在中国又有微信支付、支付宝、云闪付、等更多其他第三方支付公司,这时候策略模式就派上用场了。
1、定义策略接口,所有支付方式的接口。
import com.example.paydemo.vo.Order;
/**
* 支付接口
*/
public interface IPayService {
String pay(Order order);
}
订单vo类
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Order {
// 支付金额
private BigDecimal amount;
// 支付方式
private String paymentType;
}
2、定义各种支付策略,微信、支付宝、云闪付等支付实现类都实现这个接口。
• 微信支付实现:
import com.example.paydemo.service.IPayService;
import com.example.paydemo.vo.Order;
import org.springframework.stereotype.Service;
/**
* 微信支付实现类
*/
@Service("WechatPay")
public class WechatPayServiceImpl implements IPayService {
@Override
public String pay(Order order) {
return "微信支付成功";
}
}
• 支付宝实现:
import com.example.paydemo.service.IPayService;
import com.example.paydemo.vo.Order;
import org.springframework.stereotype.Service;
/**
* 支付宝支付实现类
*/
@Service("AliPay")
public class AliPayServiceImpl implements IPayService {
@Override
public String pay(Order order) {
return "支付宝支付成功";
}
}
• 云闪付实现:
import com.example.paydemo.service.IPayService;
import com.example.paydemo.vo.Order;
import org.springframework.stereotype.Service;
/**
* 云闪付支付实现类
*/
@Service("UnionPay")
public class UnionPayServiceImpl implements IPayService {
@Override
public String pay(Order order) {
return "云闪付支付成功";
}
}
这里我把所有支付方式类都用 @Service 注解生成 Bean 放入 Spring Bean 容器中了,在使用策略的时候就不用 new 支付对象了,可以直接使用 Bean,这样更贴近业务。
3、使用策略调用
import com.example.paydemo.service.IPayService;
import com.example.paydemo.vo.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
@RestController
public class PayController {
@Autowired
private ApplicationContext applicationContext;
/**
* 支付
*
* @param amount is 支付金额
* @param paymentType is 支付方式
* @return 支付结果
*/
@GetMapping("/pay")
public String pay(@RequestParam("amount") BigDecimal amount, @RequestParam("paymentType") String paymentType) {
Order order = new Order();
order.setAmount(amount);
order.setPaymentType(paymentType);
// 根据支付类型获取对应的策略bean
IPayService payService = applicationContext.getBean(order.getPaymentType(), IPayService.class);
// 调用支付接口
String result = payService.pay(order);
// 返回支付信息
return result;
}
}
测试一下:根据前端传入不同的支付方式参数,spring容器加载不同的实现类
测试 OK,传入不同的支付方式会调用不同的策略。