Bendi新闻
>
使用策略模式消除冗长的if-else|记一次smart-auto重构总结
使用策略模式消除冗长的if-else|记一次smart-auto重构总结
阿里妹导读
一、背景
二、现状分析
public CheckOutputModel doHandle(CheckCaseModel caseParam, BuildTestsuiteModel checkRecordModel, ExecuteResultModel executeResultModel) throws Exception {
if(!jsonPathList.isEmpty()){
if (attributeModel.isCompare()) {
HsfCheck1
}
}else{
if(attributeModel.isCompare()) {
HsfCheck2
}
}
if ( checkConfigStatusObject == null ||checkConfigStatusObject.isEmpty() || checkConfigStatusObject.getBoolean("isCheck") == false ){
return result;
}else{
if(assertExpectStr == null || !node.isCustom()){
HsfCheck3
}else{
HsfCheck4
}
}
}
"commonCheckHandlerAbandon") (
public class CommonCheckHandler implements CheckHandler{
private CaseConfigHandlerService caseConfigHandlerService;
private CheckDataCaseService checkDataCaseService;
private Logger logger = LoggerFactory.getLogger(this.getClass());
public CheckOutputModel doHandle(CheckCaseModel caseParam, BuildTestsuiteModel checkRecordModel, ExecuteResultModel executeResultModel) throws Exception {
ThubNodeConfig node = JSON.parseObject(checkRecordModel.getTestsuiteDO().getStepConfig(), ThubNodeConfig.class);
TestsuiteAttributeModel attributeModel = JSON.parseObject(checkRecordModel.getAttributes(), TestsuiteAttributeModel.class);
if (checkRecordModel.getTestsuiteDO().getShadow()) {
// 全链路压测标
EagleEye.putUserData("t", "1");
}
CheckOutputModel result = new CheckOutputModel();
if(node==null){
result.setSuccess(false);
return result;
}
List<String> jsonPathList = Collections.emptyList();
if(node.getJsonPath() != null && !node.getJsonPath().trim().isEmpty() ){
jsonPathList = Arrays.asList(node.getJsonPath().split(";"));
}
try{
//如果jsonPathList不为空,则执行jsonPath解析,执行jsonPath之后的对比
if(!jsonPathList.isEmpty()){
List<CheckDiffModel> totalFailInfo = new ArrayList<>();
List<String> errorMessages = new ArrayList<>(); // 用于存储错误消息
for (String jsonPath : jsonPathList) {
try {
if (attributeModel.isCompare()) {
String actualResultStr = StringEscapeUtils.unescapeJavaScript((String) executeResultModel.getValueByKey(CheckCaseInfoConst.ACTUAL_RESULT));
String expectResultStr = StringEscapeUtils.unescapeJavaScript((String) executeResultModel.getValueByKey(CheckCaseInfoConst.EXPECT_RESULT));
Object actualResult = null;
Object expectResult = null;
if (StringUtils.isNoneBlank(actualResultStr)) {
Object actualValueObject = JsonPath.read(actualResultStr, jsonPath);
String actualValue = JSON.toJSONString(actualValueObject);
if (JSON.isValidObject(actualValue)) {
actualResult = JSON.parseObject(actualValue);
} else if (JSON.isValidArray(actualValue)) {
actualResult = JSON.parseArray(actualValue);
} else {
actualResult = JSON.parse(actualValue);
}
}
if (StringUtils.isNoneBlank(expectResultStr)) {
Object expectValueObject = JsonPath.read(expectResultStr, jsonPath);
String expectValue = JSON.toJSONString(expectValueObject);
if (JSON.isValidObject(expectValue)) {
expectResult = JSON.parseObject(expectValue);
} else if (JSON.isValidArray(expectValue)) {
expectResult = JSON.parseArray(expectValue);
} else {
expectResult = JSON.parse(expectValue);
}
}
StringBuffer ignorBuffer = new StringBuffer();
ignorBuffer.append(node.getIgnorConfig());
List<CheckDiffModel> failInfo = QAssert.getReflectionDiffInfo("assert diff", expectResult, actualResult, ignorBuffer.toString(),
ReflectionComparatorMode.LENIENT_ORDER, ReflectionComparatorMode.LENIENT_DATES, ReflectionComparatorMode.IGNORE_DEFAULTS);
failInfo.forEach(i -> i.setNodeName(jsonPath + "---" + i.getNodeName()));
totalFailInfo.addAll(failInfo);
}
} catch (Exception e) {
// 记录错误消息
String errorMessage = "Error with JSON path: " + jsonPath + " - " + e.getMessage();
errorMessages.add(errorMessage);
logger.error(errorMessage, e);
}
}
if (!totalFailInfo.isEmpty()||!errorMessages.isEmpty()) {
if(!totalFailInfo.isEmpty()){
errorMessages.add(0, "value not same");
}
// 组合错误消息,用回车符分隔
String combinedErrorMessages = String.join("\n", errorMessages);
result.setSuccess(false);
result.setErrorCode(combinedErrorMessages);
result.setFailInfoList(totalFailInfo);
} else {
result.setSuccess(true);
}
//如果jsonPathList为空,走正常对比逻辑
}else {
result.setTraceId(EagleEye.getTraceId());
if(attributeModel.isCompare()) {
String actualResultStr = StringEscapeUtils.unescapeJavaScript((String) executeResultModel.getValueByKey(CheckCaseInfoConst.ACTUAL_RESULT));
String expectResultStr = StringEscapeUtils.unescapeJavaScript((String) executeResultModel.getValueByKey(CheckCaseInfoConst.EXPECT_RESULT));
Object actualResult = null;
Object expectResult = null;
if (StringUtils.isNoneBlank(actualResultStr)) {
if (JSON.isValidObject(actualResultStr)) {
actualResult = JSON.parseObject(actualResultStr);
} else if (JSON.isValidArray(actualResultStr)) {
actualResult = JSON.parseArray(actualResultStr);
} else {
actualResult = JSON.parse(actualResultStr);
}
}
if (StringUtils.isNoneBlank(expectResultStr)) {
if (JSON.isValidObject(expectResultStr)) {
expectResult = JSON.parseObject(expectResultStr);
} else if (JSON.isValidArray(expectResultStr)) {
expectResult = JSON.parseArray(expectResultStr);
} else {
expectResult = JSON.parse(expectResultStr);
}
}
StringBuffer ignorBuffer = new StringBuffer();
ignorBuffer.append(node.getIgnorConfig());
List<CheckDiffModel> failInfo = QAssert.getReflectionDiffInfo("assert diff", expectResult, actualResult, ignorBuffer.toString(),
ReflectionComparatorMode.LENIENT_ORDER, ReflectionComparatorMode.LENIENT_DATES, ReflectionComparatorMode.IGNORE_DEFAULTS);
if (!failInfo.isEmpty()) {
result.setSuccess(false);
result.setErrorCode("value not same");
result.setFailInfoList(failInfo);
} else {
result.setSuccess(true);
}
}
}
//执行断言校验
JSONObject checkConfigStatusObject = JSON.parseObject(checkRecordModel.getTestsuiteDO().getCheckConfigStatus());
//无断言直接返回
if ( checkConfigStatusObject == null ||checkConfigStatusObject.isEmpty() || checkConfigStatusObject.getBoolean("isCheck") == false ){
return result;
}else{
//执行断言校验
String assertActualStr = StringEscapeUtils.unescapeJavaScript((String)executeResultModel.getValueByKey(CheckCaseInfoConst.ACTUAL_RESULT));
String assertExpectStr = StringEscapeUtils.unescapeJavaScript((String)executeResultModel.getValueByKey(CheckCaseInfoConst.EXPECT_RESULT));
CheckDataCaseDO checkDataCaseDO = caseParam.getCaseDO();
//断言对比
if(assertExpectStr == null || !node.isCustom()){
boolean checkResult = caseConfigHandlerService.resultAssert(checkRecordModel.getTestsuiteDO(), checkDataCaseDO,assertActualStr);
if (!checkResult){
result.setSuccess(false);
return result;
}
CheckDataCaseQueryDO checkDataCaseQueryDO = new CheckDataCaseQueryDO();
checkDataCaseQueryDO.setId(checkDataCaseDO.getId());
List<CheckCaseResult> checkResultList = checkDataCaseService.queryCheckCaseResult(checkDataCaseQueryDO).getResult();
List<CheckDiffModel> checkCoonfigFailInfo = new ArrayList<>();
for (CheckCaseResult checkCaseResult : checkResultList) {
String checkConfigResult = checkCaseResult.getCheckConfigResult();
List<Map> checkParse = JSONArray.parseArray(checkConfigResult, Map.class);
for (Map map : checkParse) {
CheckDiffModel checkDiffModel = new CheckDiffModel();
String checkConfig = String.valueOf(map.get("checkConfigResult"));
StringBuffer stringBuffer = new StringBuffer();
if(!StringUtils.equals(checkConfig,"true")){
stringBuffer.append((String)map.get("assertNode")+map.get("assertCondition")+map.get("assertErpect"));
checkDiffModel.setActualValue("false");
checkDiffModel.setNodeName(String.valueOf(stringBuffer));
checkCoonfigFailInfo.add(checkDiffModel);
}
}
}
if (checkCoonfigFailInfo.size() != 0) {
result.setSuccess(false);
result.setErrorCode("value not same");
result.setFailInfoList(checkCoonfigFailInfo);
} else{
result.setSuccess(true);
}
//跨应用断言校验
}else {
boolean checkResult = caseConfigHandlerService.resultAssertComp(checkRecordModel.getTestsuiteDO(), checkDataCaseDO, assertActualStr,assertExpectStr);
if (!checkResult){
result.setSuccess(false);
return result;
}
CheckDataCaseQueryDO checkDataCaseQueryDO = new CheckDataCaseQueryDO();
checkDataCaseQueryDO.setId(checkDataCaseDO.getId());
List<CheckCaseResult> checkResultList = checkDataCaseService.queryCheckCaseResult(checkDataCaseQueryDO).getResult();
List<CheckDiffModel> checkCoonfigFailInfo = new ArrayList<>();
for (CheckCaseResult checkCaseResult : checkResultList) {
String checkConfigResult = checkCaseResult.getCheckConfigResult();
List<Map> checkParse = JSONArray.parseArray(checkConfigResult, Map.class);
CheckDiffModel checkDiffModel = new CheckDiffModel();
StringBuffer stringBuffer = new StringBuffer();
for (Map map : checkParse) {
Boolean checkConfig = (Boolean) map.get("checkConfigResult");
if(!checkConfig){
stringBuffer.append((String)map.get("assertNode")+map.get("assertCondition")+map.get("assertErpect"));
stringBuffer.append(",");
checkDiffModel.setActualValue("false");
}
}
checkDiffModel.setNodeName(String.valueOf(stringBuffer));
checkCoonfigFailInfo.add(checkDiffModel);
}
if (checkCoonfigFailInfo.get(0).getActualValue() != null) {
result.setSuccess(false);
result.setErrorCode("value not same");
result.setFailInfoList(checkCoonfigFailInfo);
} else{
result.setSuccess(true);
}
}
}
}catch(Exception e){
e.printStackTrace();
result.setSuccess(false);
result.setMsgInfo(e.getMessage());
}finally{
EagleEye.removeUserData("t");
}
return result;
}
}
三、解决方案
public class CheckStrategyFactory {
private final Map<CheckStrategySelector, HsfInterfaceCheck> strategyRegistry = new HashMap<>();
public CheckStrategyFactory(HsfAssertCheck hsfAssertCheck,
HsfCrossInterfaceAssertCompare hsfCrossInterfaceAssertCompare,
HsfFullCompareCheck hsfFullCompareCheck,
HsfMultipleJsonPathCompareCheck hsfMultipleJsonPathCompareCheck,
JsonPathCompareStrategySelector jsonPathCompareStrategySelector,
CrossInterfaceAssertCompareStrategySelector crossInterfaceAssertCompareStrategySelector,
FullCompareStrategySelector fullCompareStrategySelector,
AssertStrategySelector assertStrategySelector) {
// 在构造函数或初始化块中注册所有策略
strategyRegistry.put(assertStrategySelector, hsfAssertCheck);
strategyRegistry.put(crossInterfaceAssertCompareStrategySelector, hsfCrossInterfaceAssertCompare);
strategyRegistry.put(fullCompareStrategySelector, hsfFullCompareCheck);
strategyRegistry.put(jsonPathCompareStrategySelector, hsfMultipleJsonPathCompareCheck);
// ... 注册更多策略 ...
}
public HsfInterfaceCheck getStrategy(ThubNodeConfig node, JSONObject checkConfigStatusObject,TestsuiteAttributeModel attributeModel , ExecuteResultModel executeResultModel) {
for (Map.Entry<CheckStrategySelector, HsfInterfaceCheck> entry : strategyRegistry.entrySet()) {
if (entry.getKey().matches(node, checkConfigStatusObject, attributeModel, executeResultModel)) {
return entry.getValue();
}
}
return null; // 兜底检查策略返回null
}
}
public interface CheckStrategySelector {
boolean matches(ThubNodeConfig node, JSONObject checkConfigStatusObject , TestsuiteAttributeModel attributeModel , ExecuteResultModel executeResultModel);
}
public interface HsfInterfaceCheck {
CheckOutputModel check(CheckCaseModel caseParam, BuildTestsuiteModel checkRecordModel, ExecuteResultModel executeResultModel);
}
public class AssertStrategySelector implements CheckStrategySelector {
public boolean matches(ThubNodeConfig node, JSONObject checkConfigStatusObject, TestsuiteAttributeModel attributeModel , ExecuteResultModel executeResultModel) {
String assertExpectStr = StringEscapeUtils.unescapeJavaScript((String)executeResultModel.getValueByKey(CheckCaseInfoConst.EXPECT_RESULT));
return !(checkConfigStatusObject == null ||checkConfigStatusObject.isEmpty() || checkConfigStatusObject.getBoolean("isCheck") == false) && (assertExpectStr == null || !node.isCustom());
}
}
public class FullCompareStrategySelector implements CheckStrategySelector {
public boolean matches(ThubNodeConfig node, JSONObject checkConfigStatusObject, TestsuiteAttributeModel attributeModel , ExecuteResultModel executeResultModel) {
return attributeModel.isCompare() && (node.getJsonPath() == null || node.getJsonPath().trim().isEmpty());
}
}
以下是HsfCheck1和HsfCheck2校验类,省略其他2个。
"hsfAssertCheck") (
public class HsfAssertCheck implements HsfInterfaceCheck {
private CaseConfigHandlerService caseConfigHandlerService;
private CheckDataCaseService checkDataCaseService;
public CheckOutputModel check(CheckCaseModel caseParam, BuildTestsuiteModel checkRecordModel, ExecuteResultModel executeResultModel) {
}
"hsfFullCompareCheck") (
public class HsfFullCompareCheck implements HsfInterfaceCheck {
public CheckOutputModel check(CheckCaseModel caseParam, BuildTestsuiteModel checkRecordModel, ExecuteResultModel executeResultModel) {
}
}
public class CommonCheckHandler implements CheckHandler{
private final CheckStrategyFactory factory;
public CommonCheckHandler(CheckStrategyFactory factory) {
this.factory = factory;
}
public CheckOutputModel doHandle(CheckCaseModel caseParam, BuildTestsuiteModel checkRecordModel, ExecuteResultModel executeResultModel) throws Exception {
ThubNodeConfig node = JSON.parseObject(checkRecordModel.getTestsuiteDO().getStepConfig(), ThubNodeConfig.class);
TestsuiteAttributeModel attributeModel = JSON.parseObject(checkRecordModel.getAttributes(), TestsuiteAttributeModel.class);
JSONObject checkConfigStatusObject = JSON.parseObject(checkRecordModel.getTestsuiteDO().getCheckConfigStatus());
CheckOutputModel result = new CheckOutputModel();
if(node==null){
result.setSuccess(false);
return result;
}
HsfInterfaceCheck hsfInterfaceCheckStrategy = factory.getStrategy(node, checkConfigStatusObject, attributeModel, executeResultModel);
if(hsfInterfaceCheckStrategy != null){
return hsfInterfaceCheckStrategy.check(caseParam, checkRecordModel, executeResultModel);
} else {
result.setSuccess(false);
result.setErrorCode("未找到对应的校验策略");
return result;
}
}
}
四、总结
微信扫码关注该文公众号作者
来源:阿里云开发者
相关新闻
实践总结|前端架构设计的一点考究“不可变”发行版Vanilla OS 2发布稳定版:彻底重写、改变使用Linux的方式一文总结:心源性肺水肿的诊疗要点|临床必备使用 HyperLynx/ Calibre 助力您的 3D IC 电子仿真|西门子EDA在线研讨会直播预告国家药监局关于注销一次性使用静脉采血针等3个医疗器械注册证书的公告重磅|NASA官宣:与洛马合作研发超音速客机成功!短时间内投入使用,北美到中国仅6小时构建大模型一年多,我们总结了关于 LLM 应用的运营经验如何处理使用英语从事临床工作时的恐惧和焦虑?|资源推荐Nature子刊:海外团队使用可编程肽-DNA技术构建「人造细胞」,与真实细胞拥有几乎相同的外观和功能重磅!中国无证移民使用墨西哥身份证进入美国!加州枪店老板发现后院有数十本被丢弃和烧毁的护照...深夜重磅!巴菲特谈了9件重要的事:将长期持有这3只股票,今年只卖1本书,如何使用2000亿元巨款……总结|Stream流技术在真实案例中的应用罗技公司澄清 永久使用的鼠标只是一种设想而不是实际产品网络诊断工具traceroute的使用关于上市公司募集资金使用的违规案例分析港警使用的进口依维柯Daily男性避孕设计!德国设计了男性“洗蛋器”,一次使用,两个月有效!网友:果然是女设计师!麻州参议院通过限塑令!禁止使用一次性塑料袋 再生纸袋每个收10美分深入探讨:Linux防火墙配置详解及iptables与firewalld的使用最新解读|法院:数据交易买受人知道涉及商业秘密仍接收并使用的,应承担共同侵权责任,附判决书全文苹果iOS 18这个功能,可能将改变iPad的使用方式可重复使用的塑料袋也不许用!加州通过法案,禁止超市使用塑料袋苹果 iOS 18这个功能,可能将改变 iPad 的使用方式行李费省钱攻略:掌握美籍航空公司联名信用卡的使用技巧