How a Strategy Factory Refactors Complex HSF Checks for Cleaner Backend Code

This article explains how the smart‑auto testing tool’s tangled HSF interface validation logic was refactored using a strategy‑factory pattern, breaking long if‑else chains into modular strategies that improve readability, maintainability, and adherence to the Open/Closed principle.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
How a Strategy Factory Refactors Complex HSF Checks for Cleaner Backend Code

Background

The smart‑auto tool has evolved over years and now handles a wide range of HSF interface calls, accounting for more than 55% of Taobao grocery automated tests. As features grew, the core validation code became large, tangled, and hard to maintain.

Problems with Existing Code

Four HSF validation methods (HsfCheck1‑4) are combined in a single handler using lengthy if‑else branches, reducing extensibility.

The implementation violates the Open/Closed principle; any new check requires modifying the existing handler.

All validation logic resides in one massive class, harming readability and maintainability.

Complex conditionals make it difficult to determine which HSF check is being executed.

Solution: Strategy Factory Pattern

Introduce a strategy‑factory that encapsulates each HSF check in its own class and selects the appropriate strategy at runtime, thereby decoupling the validation logic.

public class CheckStrategyFactory {
    private final Map<CheckStrategySelector, HsfInterfaceCheck> strategyRegistry = new HashMap<>();

    @Autowired
    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);
        // ... register more strategies as needed
    }

    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; // fallback when no strategy matches
    }
}

Define two core interfaces:

public interface CheckStrategySelector {
    boolean matches(ThubNodeConfig node, JSONObject checkConfigStatusObject,
                    TestsuiteAttributeModel attributeModel, ExecuteResultModel executeResultModel);
}

public interface HsfInterfaceCheck {
    CheckOutputModel check(CheckCaseModel caseParam, BuildTestsuiteModel checkRecordModel,
                         ExecuteResultModel executeResultModel);
}

Example selector implementation (assert strategy):

public class AssertStrategySelector implements CheckStrategySelector {
    @Override
    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());
    }
}

Concrete check class (simplified):

@Service("hsfAssertCheck")
public class HsfAssertCheck implements HsfInterfaceCheck {
    @Resource
    private CaseConfigHandlerService caseConfigHandlerService;
    @Resource
    private CheckDataCaseService checkDataCaseService;

    @Override
    public CheckOutputModel check(CheckCaseModel caseParam, BuildTestsuiteModel checkRecordModel,
                                 ExecuteResultModel executeResultModel) {
        // implementation omitted for brevity
        return new CheckOutputModel();
    }
}

Refactored CommonCheckHandler now delegates to the factory:

@Service("commonCheckHandler")
public class CommonCheckHandler implements CheckHandler {
    private final CheckStrategyFactory factory;

    public CommonCheckHandler(CheckStrategyFactory factory) {
        this.factory = factory;
    }

    @Override
    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 strategy = factory.getStrategy(node, checkConfigStatusObject,
                                                         attributeModel, executeResultModel);
        if (strategy != null) {
            return strategy.check(caseParam, checkRecordModel, executeResultModel);
        }
        result.setSuccess(false);
        result.setErrorCode("No matching validation strategy found");
        return result;
    }
}

Benefits

The refactor follows the Open/Closed principle; new strategies can be added without touching existing code.

Validation logic is decoupled from the handler, dramatically improving readability and maintainability.

Each class now fits on a single screen, reducing cognitive load for developers.

Visual comparison of the original monolithic handler and the refactored architecture is shown below.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsStrategy PatternBackend DevelopmentCode Refactoring
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.