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.
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.
DaTaobao Tech
Official account of DaTaobao Technology
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.