用策略模式加工厂模式优化多重if-else或者switch代码

用策略模式加工厂模式优化多重if-else或者switch代码

情景:通过不同的出行方式和数量拿到不同的减碳量
代码从controller开始贴 是为了更贴近真实场景

原始代码
controller:

    /**
     *  获取减碳量
     * @param travelEnum  出行方式
     * @param number    出行数量
     * @return
     */
    @GetMapping("test2")
    public String getCarbonEmission2(@RequestParam("travelEnum")TravelEnum travelEnum,
                                    @RequestParam("number") Integer number){
        return greenTravelService.getCarbonEmission2(travelEnum,number);
    }

枚举类:
TravelEnum:

@Getter
@AllArgsConstructor
public enum TravelEnum {

    WALK(1,"步行","walkModeService"),
    RIDE(2,"骑行","rideModeService"),
    CAR(3,"开车","carModeService");

    private int type;
    private String message;
    private String beanName;  //默认注入对象名称 就是类名首字母小写

}

service:

 public String getCarbonEmission2(TravelEnum travelEnum, Integer number) {
        switch (travelEnum) {
            case WALK:
                log.info("通过一系列计算得出步行减碳为500g");
                return "通过一系列计算得出步行减碳为500g";
            case RIDE:
                log.info("通过一系列计算得出骑行减碳为350g");
                return "通过一系列计算得出骑行减碳为3500g";
            case CAR:
                log.info("通过一系列计算得出开车减碳为200g");
                return "通过一系列计算得出开车减碳为200g";
            default:
                return null;
        }
    }

改进:
controller:

    /**
     *  获取减碳量
     * @param travelEnum  出行方式
     * @param number    出行数量
     * @return
     */
    @GetMapping("test1")
    public String getCarbonEmission(@RequestParam("travelEnum")TravelEnum travelEnum,
                                    @RequestParam("number") Integer number){
        return greenTravelService.getCarbonEmission(travelEnum,number);
    }

swevice:

    
    @Autowired
    GreenTravelModeFactory greenTravelModeFactory;
    
	public String getCarbonEmission(TravelEnum travelEnum, Integer number) {
        //通过工厂拿到具体实现类的service
        GreenTravelModeService travelModeService = greenTravelModeFactory.getTravelMode(travelEnum);
        //调用具体实现类的方法
        return travelModeService.getCarbonEmission(travelEnum, number);
    }

其中 GreenTravelModeService 是一个接口:

public interface GreenTravelModeService {

    public String getCarbonEmission(TravelEnum travelEnum, Integer number);
}

GreenTravelModeService 有三个实现类,分别代表 三种不同出行方式获得减碳的具体实现逻辑

其中
WalkModeService 实现类:

@Component
@Slf4j
public class WalkModeService implements GreenTravelModeService{
    @Override
    public String getCarbonEmission(TravelEnum travelEnum, Integer number) {
        log.info("通过一系列计算得出步行减碳为500g");
        return "通过一系列计算得出步行减碳为500g";
    }

}

RideModeService 实现类:

@Component
@Slf4j
public class RideModeService implements GreenTravelModeService{
    @Override
    public String getCarbonEmission(TravelEnum travelEnum, Integer number) {
        log.info("通过一系列计算得出骑行减碳为350g");
        return "通过一系列计算得出骑行减碳为3500g";
    }
}

CarModeService 实现类:

@Component
@Slf4j
public class CarModeService implements GreenTravelModeService{
    @Override
    public String getCarbonEmission(TravelEnum travelEnum, Integer number) {
        log.info("通过一系列计算得出开车减碳为200g");
        return "通过一系列计算得出开车减碳为200g";
    }
}

上文中的: GreenTravelModeService travelModeService = greenTravelModeFactory.getTravelMode(travelEnum);
就是通过工厂拿到 真正执行这个 GreenTravelModeService 的实现类,怎末拿? 看下面代码。

GreenTravelModeFactory:

@Component
public class GreenTravelModeFactory {

    public GreenTravelModeService getTravelMode(TravelEnum travelEnum){
        //通过springContext上下文对象拿到容器中的service
        return SpringContextUtil.getBean(travelEnum.getBeanName(),GreenTravelModeService.class);
    }

}

通过自定义的 SpringContextUtil 拿到容器中的对象,因为前面三个实现类都已经注入到spring容器中(@Component),且注入的对象名称就是 类名将首字母小写

SpringContextUtil:

@Component
@Slf4j
public class SpringContextUtil implements ApplicationContextAware {

    @PostConstruct
    private void init(){
        System.out.println(applicationContext);
    }

    private static ApplicationContext applicationContext;

    public static<T> T getBean(String name,Class<T> classs){
        //通过容器中对象的name以及class类型拿到对象
        return applicationContext.getBean(name,classs);
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }
}

该类通过实现 ApplicationContextAware 从而拿到 applicationContext 从而 能够到容器中拿到对象,项目启动,
setApplicationContext 该方法就会执行。

你可能感兴趣的:(java,策略模式,开发语言)