springboot 使用工厂模式+策略模式替代多重if 案例

项目背景:

由于做的是物联网项目,现在需要实现的是网关入网+子设备注册;网关有3个逻辑,分别为首次入网、解绑后同一个人入网(恢复)、解绑后换人入网(换人)、子设备注册;

原先写法是:

if(type == 1){
    doSomeThing()   //首次入网
}else if(type == 2){
    doSomeThing()   //恢复
}else if(type == 3){
    doSomeThing()   //换人注册
}else if(type == 4){
    doSomeThing()   //子设备注册
}

采用这种方式即代码无法复用,存在许多重复代码块。代码都是垂直写到底,然后换另一个type 也是垂直写到底 ;并且每个 if 中若逻辑复杂,其实代码看起来也非常晦涩;

采用工厂模式 + 策略模式

定义策略接口:

package com.xhwl.smarthome.service;


/**
 * @author wangxinyu
 * * @date 2021/11/19
 * 设备注册策略接口
 */
public interface DeviceRegisterStrategy {

    Object callIoTRegisterDevice(xxxx);

}

定义策略实现类:

首次入网:

package com.xhwl.smarthome.service.impl;


/**
 * @author wangxinyu
 * @since 2021/11/19
 * 首次注册策略(网关)
 */
@Component
public class FirstRegStrategy implements DeviceRegisterStrategy {

    @Override
    public Object callIoTRegisterDevice(xxxxx){
          doSomeThing();    //自定义策略逻辑
    }
}

 恢复(解绑后同一个人入网):

package com.xhwl.smarthome.service.impl;


/**
 * @author wangxinyu
 * @since 2021/11/19
 * 同个人二次注册同一网关设备策略
 */
@Component
public class RecoverRegStrategy implements DeviceRegisterStrategy {

    @Override
    public Object callIoTRegisterDevice(xxxx) {
        doSomeThing(); //自定义策略逻辑
    }

}

换人注册:

package com.xhwl.smarthome.service.impl;



/**
 * @author wangxinyu
 * @since 2021/11/19
 * 换人后注册网关设备策略
 */
@Component
public class ReplaceRegStrategy implements DeviceRegisterStrategy {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object callIoTRegisterDevice(xxxxx) {
        doSomeThing();  //自定义逻辑
    }
}

子设备注册:

package com.xhwl.smarthome.service.impl;


/**
 * @author wangxinyu
 * @since 2022/1/4
 * 子设备注册策略,与网关分开有以下几个考虑:
 * 1、网关逻辑不需要这么多产品校验加工(子设备) , 业务剥离
 * 2、子设备注册返回参数与网关已经不同
 * 3、子设备后续会不断新增加工逻辑,而网关不需要;
 */
@Slf4j
@Component
public class SubDeviceRegStrategy implements DeviceRegisterStrategy {

    @Override
    public Object callIoTRegisterDevice(xxxxxxx) {
        doSomeThing();  //自定义逻辑
    }
}

策略类都定义完了,现在则需要一个工厂模式将其加入到Spring中管理,并在需要时依赖注入

定义一个工厂类:

package com.xhwl.smarthome.factory;

import com.xhwl.smarthome.service.DeviceRegisterStrategy;
import com.xhwl.smarthome.service.impl.FirstRegStrategy;
import com.xhwl.smarthome.service.impl.RecoverRegStrategy;
import com.xhwl.smarthome.service.impl.ReplaceRegStrategy;
import com.xhwl.smarthome.service.impl.SubDeviceRegStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wangxinyu
 * @since 2021/11/19
 */
@Component
public class DeviceRegisterStrategyFactory {

    private static final Map map = new HashMap<>(4);

    @Autowired
    private FirstRegStrategy firstRegStrategy;

    @Autowired
    private RecoverRegStrategy recoverRegStrategy;

    @Autowired
    private ReplaceRegStrategy replaceRegStrategy;

    @Autowired
    private SubDeviceRegStrategy subDeviceRegStrategy;

    @PostConstruct
    public void initDeviceRegisterStrategy(){
        map.put("FirstRegister",firstRegStrategy);
        map.put("RecoverRegister",recoverRegStrategy);
        map.put("ReplaceRegister",replaceRegStrategy);
        map.put("SubDeviceRegister",subDeviceRegStrategy);
    }

    public static DeviceRegisterStrategy getDeviceRegisterStrategy(String name) {
        return map.get(name);
    }

}

目前改造已经完毕 , 使用时只需要通过工厂类的静态方法 getDeviceRegisterStrategy() 接收一个策略 name 即可 ;为了便于管理 ,name 也可以定义枚举类 ;

package com.xhwl.smarthome.pojo.enums;

/**
 * @author wangxinyu
 * * @date 2021/11/19
 */
public enum RegisterEnum {
    FIRST_REG(1,"FirstRegister"),
    RECOVER_REG(2,"RecoverRegister"),
    REPLACE_REG(3,"ReplaceRegister"),
    SUB_DEVICE_REG(4,"SubDeviceRegister");

    private int type;

    private String name;

    public int getType() {
        return type;
    }

    public String getName() {
        return name;
    }

    RegisterEnum(int type, String name) {
        this.type = type;
        this.name = name;
    }

    RegisterEnum(){}

    public static RegisterEnum of(int type){
        for (RegisterEnum e : RegisterEnum.values()) {
            if(e.getType() == type){
                return e;
            }
        }
        return null;
    }
}

至此,全篇结束,欢迎大佬们指点;

你可能感兴趣的:(设计模式,spring,boot,策略模式,后端)