Backend Development 13 min read

Refactoring Java Sale‑Type Parsing: From Simple Method to Design Patterns

Starting from a basic Java method that maps a sale‑type string to an integer, the article incrementally refactors the code by applying null‑safe utilities, constants, static methods, ternary/Optional expressions, enums with lookup maps, a combined relation enum, and finally a Strategy pattern with a container, illustrating how each step improves safety, readability, extensibility, and testability.

DaTaobao Tech
DaTaobao Tech
DaTaobao Tech
Refactoring Java Sale‑Type Parsing: From Simple Method to Design Patterns

The article starts with a simple Java method that converts an external sale‑type identifier to an internal numeric code:

public Integer parseSaleType(String saleTypeStr){
  if(saleTypeStr == null || saleTypeStr.equals("")){
    return null;
  }
  if(saleTypeStr.equals("JX")){
    return 1;
  }
  return null;
}

Although functionally correct, the author points out several style and safety issues and proposes a series of incremental improvements.

1. Use functional utilities instead of manual null checks

// Objects.isNull(saleTypeStr)
if(StringUtils.isBlank(saleTypeStr)){
    return null;
}

2. Put constant values in a dedicated field

private static final String JX_SALE_TYPE_STR = "JX";
private static final Integer JX_SALE_TYPE_INT = 1;

3. Declare the method static when it has no state

public static Integer parseSaleType(String saleTypeStr){
    // …
}

4. Simplify the logic with a ternary operator or Optional

return JX_SALE_TYPE_STR.equals(saleTypeStr) ? JX_SALE_TYPE_INT : null;
return Optional.ofNullable(saleTypeStr)
    .filter(JX_SALE_TYPE_STR::equals)
    .map(o -> JX_SALE_TYPE_INT)
    .orElse(null);

5. Replace magic strings with enums

public enum SaleTypeStrEnum{ JX, /* OTHERS */ }

public enum SaleTypeIntEnum{ JX(1), /* OTHERS */ ;
    private Integer code;
}

Using enums enables O(1) lookup via a pre‑built map:

private static final Map
NAME_MAP =
    Arrays.stream(SaleTypeStrEnum.values())
          .collect(Collectors.toMap(SaleTypeStrEnum::name, Function.identity()));

public static SaleTypeStrEnum getByName(String s){
    return NAME_MAP.get(s);
}

The parsing method can then be written with a switch:

public static Integer parseSaleType(String saleTypeStr){
    switch(SaleTypeStrEnum.getByName(saleTypeStr)){
        case JX: return SaleTypeIntEnum.JX.getCode();
        // OTHERS
        default: return null;
    }
}

6. Combine the two enums into a single relation enum

@Getter @AllArgsConstructor
public enum SaleTypeRelEnum {
    JX("JX", 1),
    // OTHERS
    ;
    private String fromCode;
    private Integer toCode;
    private static final Map
FROM_CODE_MAP =
        Arrays.stream(values()).collect(Collectors.toMap(SaleTypeRelEnum::getFromCode, Function.identity()));
    public static Integer parseCode(String s){
        return Optional.ofNullable(FROM_CODE_MAP.get(s))
                       .map(SaleTypeRelEnum::getToCode)
                       .orElse(null);
    }
}

7. Introduce a Strategy pattern for extensibility

public interface SaleTypeParseStrategy{
    Integer parse(SaleTypeParseContext ctx);
}

public class JxSaleTypeParseStrategy implements SaleTypeParseStrategy{
    @Override
    public Integer parse(SaleTypeParseContext ctx){
        return SaleTypeIntEnum.JX.getCode();
    }
}

@Data
public class SaleTypeParseContext{
    private SaleTypeStrEnum saleTypeStr;
    private SaleTypeParseStrategy strategy;
    public Integer execute(){
        return strategy.parse(this);
    }
}

The client builds a context, selects a strategy (e.g., via a switch or a container), and calls context.execute() .

8. Decouple strategy registration with a container (manual or Spring‑based)

public static class SaleTypeParseStrategyContainer{
    private static final Map
MAP = new HashMap<>();
    @PostConstruct
    public void init(){
        MAP.put(SaleTypeStrEnum.JX, new JxSaleTypeParseStrategy());
        // add more strategies
    }
    public Integer parse(SaleTypeParseContext ctx){
        return Optional.ofNullable(MAP.get(ctx.getSaleTypeStr()))
                       .map(s -> s.parse(ctx))
                       .orElse(null);
    }
}

When using Spring, the container can autowire all SaleTypeParseStrategy beans and build the map automatically.

Finally, the author reflects that the same problem can be solved with a single line of code, but the step‑by‑step evolution demonstrates how design patterns, enums, and containers can be introduced gradually to support future extensions, maintainability, and testability.

design patternsJavaStrategy Patterncode refactoringenumOptional
DaTaobao Tech
Written by

DaTaobao Tech

Official account of DaTaobao Technology

0 followers
Reader feedback

How this landed with the community

login 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.