1.什么是策略模式?
策略模式是对算法的包装,是把使用的算法的责任和算法分割开来,委派给不同的对象管理,最终可以实现解决多重if判断问题。
下面会连接数据库使用
效果如下
项目结构如下
开始上代码
1.创建数据库
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for payment_channel
-- ----------------------------
DROP TABLE IF EXISTS `payment_channel`;
CREATE TABLE `payment_channel` (
`ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`CHANNEL_NAME` varchar(32) NOT NULL COMMENT '渠道名称',
`CHANNEL_ID` varchar(32) NOT NULL COMMENT '渠道ID',
`strategy_bean_id` varchar(255) DEFAULT NULL COMMENT '策略执行beanid',
PRIMARY KEY (`ID`,`CHANNEL_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='支付渠道 ';
-- ----------------------------
-- Records of payment_channel
-- ----------------------------
BEGIN;
INSERT INTO `payment_channel` VALUES (4, '支付宝渠道', 'ali_pay', 'aliPayStrategy');
INSERT INTO `payment_channel` VALUES (5, '微信支付渠道', 'weixin_pay', 'weiXinPayStrategy');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
2.创建项目 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.daiison</groupId>
<artifactId>design_strategy</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
配置文件application.yml
###服务启动端口号
server:
port: 80
spring:
###数据库相关连接
datasource:
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/design?useUnicode=true&characterEncoding=UTF-8
####打印MyBatias日志
logging:
level:
### 开发环境使用DEBUG 生产环境info或者error
com.mayikt.daiison.mapper: DEBUG
启动类
@SpringBootApplication
@MapperScan("com.daiison")
public class PayApplication {
public static void main(String[] args) {
SpringApplication.run(PayApplication.class, args);
}
}
可以通过具体的类过去小写的类名称
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.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);
}
}
pojo
@Data
public class PaymentChannel {
/** ID */
private Integer id;
/** 渠道名称 */
private String channelName;
/** 渠道ID */
private String channelId;
/**
* 策略执行beanId
*/
private String strategyBeanId;
}
重点
/**
* @auther daiison
* @create 2020-03-2020/3/19-10:26 上午
* 策略上下文 更具具体的枚举 调用具体的策略实现
**/
@Component
public class PayContextStrategy {
@Autowired
private PaymentChannelMapper paymentChannelMapper;
public String toPayHtml(String payValue) {
//1.使用payValue查询数据库获取beanId
PaymentChannel paymentChannel = paymentChannelMapper.getPaymentChannel(payValue);
if (paymentChannel==null) {
return "没有该渠道信息";
}
//2.获取到bean的id之后,使用spring容器获取实例对象
String strategyBeanId = paymentChannel.getStrategyBeanId();
if(StringUtils.isEmpty(strategyBeanId)){
return "该渠道没有配置beanid";
}
//<bean id="aliPayStrategy" class="com.daiison.service.impl.AliPayStrategy">
PayStrategy payStrategy = SpringUtils.getBean(strategyBeanId, PayStrategy.class);
return payStrategy.toPayHtml();
// 优化 支付渠道存放内存中...
}
}
@Data
public class PaymentChannel {
/** ID */
private Integer id;
/** 渠道名称 */
private String channelName;
/** 渠道ID */
private String channelId;
/**
* 策略执行beanId
*/
private String strategyBeanId;
}
mapper
import com.daiison.pojo.PaymentChannel;
import org.apache.ibatis.annotations.Select;
public interface PaymentChannelMapper {
@Select("\n" +
"SELECT id as id ,CHANNEL_NAME as CHANNELNAME ,CHANNEL_ID as CHANNELID,strategy_bean_id AS strategybeanid\n" +
"FROM payment_channel where CHANNEL_ID=#{payCode}")
public PaymentChannel getPaymentChannel(String payCode);
}
公共支付接口
public interface PayStrategy {
/**
* 定义共同方法的行为
* @return
*/
public String toPayHtml();
}
各个支付具体实现接口,这里用支付宝和微信支付
@Component
public class AliPayStrategy implements PayStrategy {
//<bean id="aliPayStrategy" class="com.daiison.service.impl.AliPayStrategy">
//使用类名小写,从spring容器中获取具体策略对象
@Override
public String toPayHtml() {
return "调用支付宝!";
}
}
@Component
public class WeiXinPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "微信支付!";
}
}
最后controller调研即可
@RestController
public class PayController {
@Autowired
private PayContextStrategy payContextStrategy;
@RequestMapping("toPayHtml")
public String toPayHtml(String payValue){
return payContextStrategy.toPayHtml(payValue);
}
}
来源:oschina
链接:https://my.oschina.net/u/4182459/blog/3198067