设计模式之策略模式

  • 场景

一般情况下我们会想到使用if...else,如下代码。但是实际的业务场景肯定不止这四种,随着条件越来也来,代码就显得非常的臃肿和难以维护。(也可以使用switch来实现,这里就不赘述了)

  1. package com.example.designpattern.celuemoshi.old;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author shkstart
     * @create 2021-07-11 22:16
     */
    @RestController
    @RequestMapping("/testController")
    public class TestController {
    
        @RequestMapping("/arithmetic02")
        public double arithmetic02(String arithmeticType, int startNum, int endNum) {//arithmetic算术
            double result = 0.0;
            if (arithmeticType.equals("addition")) {
                result = startNum + endNum;
            } else if (arithmeticType.equals("subtraction")) {
                result = startNum - endNum;
            } else if (arithmeticType.equals("multiplication")) {
                result = startNum * endNum;
            } else {
                result = startNum / endNum;
            }
            System.out.println("====================>" + result);
            return result;
        }
    }

    调用地址:http://localhost:8080/testController/arithmetic02?arithmeticType=addition&startNum=5&endNum=5

  • 重构:下面使用策略设计模式,对业务进行重构

创建一个接口类:BaseHandler

  1. package com.example.designpattern.celuemoshi.firstvesion;
    
    /**
     * @author shkstart
     * @create 2021-07-11 22:23
     */
    public interface BaseHandler {
    //    public  double result = 0.0;
    
        public double arithmetic(int startNum, int endNum);
    }

创建加减乘法四种业务对应的接口实现类

  • 加法实现类 
  1. package com.example.designpattern.celuemoshi.firstvesion;
    
    import org.springframework.stereotype.Service;
    
    /**
     * @author shkstart
     * @create 2021-07-11 22:25
     */
    @Service("addition")
    public class AdditionHandler implements BaseHandler{
    
        @Override
        public double arithmetic(int startNum, int endNum) {
           return startNum + endNum;
    
        }
    }
  •  减法实现类
  1. package com.example.designpattern.celuemoshi.firstvesion;
    
    import org.springframework.stereotype.Service;
    
    /**
     * @author shkstart
     * @create 2021-07-11 22:30
     */
    @Service("subtraction")
    public class SubtractionHandler implements  BaseHandler {
        @Override
        public double arithmetic(int startNum, int endNum) {
            return  startNum - endNum;
        }
    }
  • 乘法实现类 
  1. package com.example.designpattern.celuemoshi.firstvesion;
    
    import org.springframework.stereotype.Service;
    
    /**
     * @author shkstart
     * @create 2021-07-11 22:31
     */
    @Service("multiplication")
    public class MultiplicationHandler implements  BaseHandler{
        @Override
        public double arithmetic(int startNum, int endNum) {
            return startNum * endNum;
        }
    }
  • 除法实现类 
  1. package com.example.designpattern.celuemoshi.firstvesion;
    
    import org.springframework.stereotype.Service;
    
    /**
     * @author shkstart
     * @create 2021-07-11 22:32
     */
    @Service("division")
    public class DivisionHandler implements BaseHandler {
        @Override
        public double arithmetic(int startNum, int endNum) {
            return startNum / endNum;
        }
    }

Controller类代码,使用@Autowired将BaseHandler注入

  1. package com.example.designpattern.celuemoshi.firstvesion;
    
    import javafx.application.Application;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.Map;
    
    /**
     * @author shkstart
     * @create 2021-07-11 22:16
     */
    @RestController
    @RequestMapping("/testController2")
    public class TestController2 {
        @Autowired
        private Map<String,BaseHandler> handlerMap;
    
    
        @RequestMapping("/arithmetic")
        public double arithmetic02(String arithmeticType, int startNum, int endNum) {//arithmetic算术
            BaseHandler baseHandler = handlerMap.get(arithmeticType);
            double arithmetic = baseHandler.arithmetic(startNum, endNum);
            return arithmetic;
        }
    }

    调用地址:http://localhost:8080/testController2/arithmetic?arithmeticType=addition&startNum=5&endNum=5

@component注解会把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="",class=""/>,启动项目时加载到handlerMap中,下面通过debug调试查看

 

思考如果这种方法不可行,我们可以采用工厂模式来完成

 定义枚举

package com.example.designpattern.celuemoshi.secondvesion.enmu;



/**
 * @author shkstart
 * @create 2021-07-11 23:12
 */
public enum  ArithmeticEnum {
    addition("addition","com.example.designpattern.celuemoshi.firstvesion.AdditionHandler"),
    division("division","com.example.designpattern.celuemoshi.firstvesion.DivisionHandler"),
    multiplication("multiplication","com.example.designpattern.celuemoshi.firstvesion.MultiplicationHandler"),
    subtraction("subtraction","com.example.designpattern.celuemoshi.firstvesion.SubtractionHandler");
    String type;
    String value;

    private ArithmeticEnum(String type, String value) {
        this.type = type;
        this.value = value;
    }



    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public java.lang.String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public static ArithmeticEnum getObj(java.lang.String type){
        for (ArithmeticEnum e : ArithmeticEnum.values()) {
            if(type.equals(e.getType())){
                return e;
            }
        }
        return null;
    }
}

定义工厂类

package com.example.designpattern.celuemoshi.secondvesion;

import com.example.designpattern.celuemoshi.firstvesion.BaseHandler;
import com.example.designpattern.celuemoshi.secondvesion.enmu.ArithmeticEnum;


/**
 * @author shkstart
 * @create 2021-07-11 23:08
 * 使用工厂模式创建对象
 */
public class StrategyFacade {

    public BaseHandler getStrategyType(String arithmeticType) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        ArithmeticEnum obj = ArithmeticEnum.getObj(arithmeticType);

        BaseHandler o = (BaseHandler) Class.forName(obj.getValue()).newInstance();
        return o;
    }
}

定义controller

package com.example.designpattern.celuemoshi.secondvesion;

import com.example.designpattern.celuemoshi.firstvesion.BaseHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * @author shkstart
 * @create 2021-07-11 22:16
 */
@RestController
@RequestMapping("/testController3")
public class TestController3 {



    @RequestMapping("/arithmetic")
    public double arithmetic02(String arithmeticType, int startNum, int endNum) throws IllegalAccessException, InstantiationException, ClassNotFoundException {//arithmetic算术
        StrategyFacade strategyFacade = new StrategyFacade();
        BaseHandler strategyType = strategyFacade.getStrategyType(arithmeticType);
        double arithmetic = strategyType.arithmetic(startNum, endNum);
        return arithmetic;
    }
}

调用地址:http://localhost:8080/testController3/arithmetic?arithmeticType=addition&startNum=5&endNum=5

  • 总结

  1. @component将所有的bean实例化到Spring中,是一个map格式,@component注解的属性值就是map的key。
  2. 使用设计模式完全避免了大量的if...else,代码看起来简洁,便于后期扩展和维护。
  3. 后期新增业务只需关注自己的业务点,不需要新增逻辑判断。
  4. 缺点就是需要创建很多的实现类。
原文地址:https://www.cnblogs.com/cj8357475/p/15000194.html