项目背景:
由于做的是物联网项目,现在需要实现的是网关入网+子设备注册;网关有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;
}
}
至此,全篇结束,欢迎大佬们指点;