设计模式-策略模式【一】

半世苍凉 提交于 2020-03-19 12:50:23

3 月,跳不动了?>>>

 

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);
    }


}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!