Java 设计模式--策略模式,枚举+工厂方法实现

项目中的一个页面跳转功能存在10个以上的if else判断,想要做一下整改

一、什么是策略模式

策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,最终可以实现解决多重If判断问题。

1.环境(Context)角色:持有一个Strategy的引用。

2.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

3.具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

(定义策略接口→实现不同的策略类→利用多态或其他方式调用策略。)

二、策略模式优缺点

优点:

算法可以自由切换(高层屏蔽算法,角色自由切换)

避免使用多重条件判断(如果算法过多就会出现很多相同的判断,很难维护)

扩展性好(可自由添加取消算法,而不影响整个功能)

缺点:

策略数量增多(每一个策略类复用性小,如果需要增加算法,就只能新增类)

所有的策略类都需要对外暴露(使用的人必须了解使用策略,这个就需要其他模式来补充,比如工厂模式、代理模式)

三、代码示例

 1.定义共同的方法和行为 

package com.ultiwill.strategy;

public interface PayStrategy {

    /**
     * 共同的行为方法
     * @return
     */
    String toPayHtml();

}

2. 三种具体策略的实现  (阿里支付, 微信支付, 小米支付)

package com.ultiwill.strategy.impl;

import com.ultiwill.strategy.PayStrategy;

/**
 * @author chong.zuo
 * @date 2020/9/24 15:21
 */
public class AliPayStrategy implements PayStrategy {

    @Override
    public String toPayHtml() {
        return "调用阿里支付...AliPayStrategy";
    }
}
package com.ultiwill.strategy.impl;

import com.ultiwill.strategy.PayStrategy;

/**
 * @author chong.zuo
 * @date 2020/9/24 15:29
 */
public class WeChatPayStrategy implements PayStrategy {
    @Override
    public String toPayHtml() {
        return "调用微信支付...WeChatPayStrategy";
    }
}
package com.ultiwill.strategy.impl;

import com.ultiwill.strategy.PayStrategy;

/**
 * @author chong.zuo
 * @date 2020/9/24 15:34
 */
public class XiaomiPayStrategy implements PayStrategy {
    @Override
    public String toPayHtml() {
        return "调用小米支付...XiaomiPayStrategy";
    }
}

3. 枚举类定义映射地址

package com.ultiwill.strategy.enums;

import org.apache.commons.lang.StringUtils;

/**
 * 枚举
 * @author chong.zuo
 * @date 2020/9/24 15:45
 */
public enum PayEnumStrategy {
    /**
     * 阿里支付
     */
    ALI_PAY("1","com.ultiwill.strategy.impl.AliPayStrategy"),
    /**
     * 微信支付
     */
    WECHAT_PAY("2","com.ultiwill.strategy.impl.WeChatPayStrategy"),
    /**
     * 小米支付
     */
    XIAOMI_PAY("3","com.ultiwill.strategy.impl.XiaomiPayStrategy");


    private String code;
    private String className;

    PayEnumStrategy() {
    }

    PayEnumStrategy(String code, String className) {
        this.code = code;
        this.className = className;
    }

    public static String getClassNameByCode(String code) {
        String className = "";
        if (StringUtils.isEmpty(code)) {
            return className;
        }

        for (PayEnumStrategy e : PayEnumStrategy.values()) {
            if (e.code.equalsIgnoreCase(code)) {
                className = e.className;
                break;
            }
        }
        return className;
    }

    public String getCode() {
        return code;
    }

    public String getClassName() {
        return className;
    }
    
}

4.工厂类反射执行

package com.ultiwill.strategy.factory;

import com.ultiwill.strategy.PayStrategy;
import com.ultiwill.strategy.enums.PayEnumStrategy;

/**
 * @author chong.zuo
 * @date 2020/9/24 16:10
 */
public class StrategyFactory {

    /**
     * 使用策略工厂获取具体策略实现
     * @param code
     * @return
     */
    public static PayStrategy getPayStrategy(String code) {
        try {
            return (PayStrategy) Class.forName(PayEnumStrategy.getClassNameByCode(code)).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

5.上下文获取具体策略 

package com.ultiwill.strategy.context;

import com.ultiwill.strategy.PayStrategy;
import com.ultiwill.strategy.enums.PayEnumStrategy;
import com.ultiwill.strategy.factory.StrategyFactory;
import org.apache.commons.lang.StringUtils;

/**
 * 上下文
 *
 * @author chong.zuo
 * @date 2020/9/24 15:41
 */
public class PayContextStrategy {

    /**
     * 获取具体的策略实现
     *
     * @param code
     * @return
     */
    public static String toPayHtml(String code) {
        if (StringUtils.isBlank(code)) {
            return "code不能为空...";
        }
        PayStrategy payStrategy = StrategyFactory.getPayStrategy(code);
        if (payStrategy == null) {
            return "没有找到具体的策略...";
        }
        return payStrategy.toPayHtml();
    }
}

四、测试

controller:

package com.ultiwill.controller;

import com.ultiwill.strategy.context.PayContextStrategy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author c
 * @date 2020/5/14 9:59
 */
@RestController
public class TestController {

    @RequestMapping("/helloworld")
    public String hello(String code) {
        return PayContextStrategy.toPayHtml(code);
        /*if ("0".equals(code)) {
            return "调用阿里支付...AliPayStrategy";
        } else if ("1".equals(code)) {
            return "调用微信支付...AliPayStrategy";
        } else if ("2".equals(code)) {
            return "调用小米支付...AliPayStrategy";
        }
        return "调用接口不存在";
        */
    }

}
View Code

pom:

<?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.ultiwill</groupId>
    <artifactId>springboot-jar</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <version>2.1.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>2.1.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.1.8.RELEASE</version>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                    <mainClass>com.ultiwill.Application</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>
View Code

 五、成功

 

 

原文地址:https://www.cnblogs.com/chong-zuo3322/p/13724847.html