1.現在有一個需求,根據不同的傳參payCode選擇不同的支付模式 ,
常見的if判斷如下
public String toPayHtml(String payCode){
if("ALI_PAY".equals(payCode)){
return "使用支付寶支付....";
}else if ("WEIXIN_PAY".equals(payCode)){
return "使用微信支付....";
}else if ("XIAOMI".equals(payCode)){
return "使用小米支付....";
}
return null;
}
策略模式實現1
源碼鏈接:https://pan.baidu.com/s/1-RwF4IIKNMzDww4UIJIjkA 提取碼:adua
1.定義接口, 定義共同行爲方法
public interface PayStrategy {
//共同方法行爲
String toPayHtml();
}
2.分別定義實現類,支付寶支付,微信支付,小米支付
public class AliPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "調用支付寶接口.....";
}
}
public class WeiXinPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "調用微信支付....";
}
}
public class XiaoMiPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "調用小米支付....";
}
}
3.定義枚舉類型,存放所有策略的實現
//策略枚舉類,存放所有策略的實現
public enum PayEnumStrategy {
//支付寶支付
ALI_PAY("com.zhang.strategy.impl.AliPayStrategy"),
//小米支付
XIAOMI_PAY("com.zhang.strategy.impl.XiaoMiPayStrategy"),
//微信支付
WECHAT_PAY("com.zhang.strategy.impl.WeiXinPayStrategy");
PayEnumStrategy(String className){
this.setClassName(className);
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
//class完整地址
private String className;
}
4.使用工廠初始化實現策略ben,獲取具體策略實現
public class StrategyFactory {
//使用策略工廠獲取具體策略實現
public static PayStrategy getPayStrategy(String stratrgyType){
try {
//獲取具體的策略class地址
String className = PayEnumStrategy.valueOf(stratrgyType).getClassName();
return (PayStrategy)Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
5.定義上下文,獲取具體實現策略,並執行對應策略
@Component
public class PayContextStrategy {
public String toPayHtml(String payCode){
if(StringUtils.isEmpty(payCode)){
return "payCode不能爲空!...";
}
PayStrategy payStrategy = StrategyFactory.getPayStrategy(payCode);
if(payStrategy==null){
return "沒有找到具體策略的實現";
}
return payStrategy.toPayHtml();
}
}
6.測試
@RestController
public class PayControlller {
@Autowired
private PayContextStrategy payContextStrategy;
@GetMapping("/toPayHtml")
public String toPayHtml(String payCode){
return payContextStrategy.toPayHtml(payCode);
}
}
策略模式實現2 -通過數據庫管理更優
源碼鏈接:https://pan.baidu.com/s/1M7UM-TW3BDgaJ0EXKtrjCw
提取碼:fhvb
1.定義接口, 定義共同行爲方法
public interface PayStrategy {
//共同方法行爲
String toPayHtml();
}
2.分別定義實現類,支付寶支付,微信支付,小米支付,並注入到Spring容器
@Component
public class AliPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "調用支付寶接口.....";
}
}
@Component
public class WeiXinPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "調用微信支付....";
}
}
@Component
public class XiaoMiPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "調用小米支付....";
}
}
3.數據庫存儲所有策略實現,後期可配置控制是否開啓處理
CREATE TABLE `strategy` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
`change_name` varchar(50) DEFAULT NULL COMMENT '名稱',
`change_id` varchar(50) DEFAULT NULL COMMENT 'key_id',
`change_ben_name` varchar(255) DEFAULT NULL COMMENT '實現類名',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
4.編輯策略上下文,獲取具體策略
@Component
public class PayContextStrategy {
@Autowired
private PayStrategyMapper getPayStrategyMapper;
public String toPayHtml(String payCode){
if(StringUtils.isEmpty(payCode)){
return "payCode不能爲空!...";
}
//查詢數據庫獲取pay策略實體
PayStrategyEntity payStrategyEntity = getPayStrategyMapper.getStrategyEntity(payCode);
if(payStrategyEntity==null){
return "數據庫沒有找到具體策略的實現";
}
//獲取執行策略的類名-首字母小寫
String changeBenName = payStrategyEntity.getChangeBenName();
if(StringUtils.isEmpty(changeBenName)){
return "沒有找到具體策略的實現";
}
//通過spring找到策略ben對象
PayStrategy payStrategy = SpringUtils.getBean(changeBenName, PayStrategy.class);
//執行策略
return payStrategy.toPayHtml();
}
}
5.Spring上下文獲取Spring注入ben對象工具類
//spring上下文中獲取ben對象
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtils.applicationContext == null) {
SpringUtils.applicationContext = applicationContext;
}
}
//獲取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通過name獲取 Bean.
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
//通過class獲取Bean.
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
//通過name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
6.實體 和 mapper就不貼了 ,測試
@RestController
public class PayControlller {
@Autowired
private PayContextStrategy payContextStrategy;
@GetMapping("/toPayHtml")
public String toPayHtml(String payCode){
return payContextStrategy.toPayHtml(payCode);
}
}