好好的“代码优化”是怎么一步步变成“过度设计”的
public Integer parseSaleType(String saleTypeStr){if(saleTypeStr == null || saleTypeStr.equals("")){return null;}if(saleTypeStr.equals("JX")){return 1;}return null;}
//saleTypeStr == nullObjects.isNull(saleTypeStr)
容易漏逻辑,尽量使用现成的方法
//if(saleTypeStr == null || saleTypeStr.equals(""))if(StringUtils.isBlank(saleTypeStr))
//if(saleTypeStr.equals("JX"))if("JX".equals(saleTypeStr))
private static final String JX_SALE_TYPE_STR = "JX";private static final Integer JX_SALE_TYPE_INT = 1;
//public Integer parseSaleType(String saleTypeStr)public static Integer parseSaleType(String saleTypeStr)
方法本身跟所在类的实例对象状态无关,且不会诱发线程安全问题,故符合被定义为static的条件,可先于对象创建在方法区,防止每个对象创建一次的时候,堆内存创建一次。
private static final String JX_SALE_TYPE_STR = "JX";private static final Integer JX_SALE_TYPE_INT = 1;public static Integer parseSaleType(String saleTypeStr){if(JX_SALE_TYPE_STR.equals(saleTypeStr)){return JX_SALE_TYPE_INT;}return null;}
public static Integer parseSaleType(String saleTypeStr){return JX_SALE_TYPE_STR.equals(saleTypeStr) ? JX_SALE_TYPE_INT : null;}
public static Integer parseSaleType(String saleTypeStr){Optional.ofNullable(saleTypeStr).filter(JX_SALE_TYPE_STR::equals).map(o -> JX_SALE_TYPE_INT).orElse(null);}
- 未来除了一种逻辑分支外,还会扩展其他分支,并且有被扩展的可能;
- 虽然还是一种逻辑分支,但是判断的内容变长了,跟上下文和调用状态有关;
- 虽然还是一种逻辑分支,但是逻辑总在调整;
- 一处定义,多点引用;

public enum SaleTypeStrEnum{JX,// OTHERS;}public enum SaleTypeIntEnum{JX(1),// OTHERS;private Integer code;}
public enum SaleTypeStrEnum{JX,// OTHERS;public static SaleTypeStrEnum getByName(String saleTypeStr){for (SaleTypeStrEnum value : SaleTypeStrEnum.values()) {if(value.name().equals(saleTypeStr)){return value;}}return null;}}
public enum SaleTypeStrEnum{JX,// OTHERS;/*** 预热转换关系到内存*/private static Map<String, SaleTypeStrEnum> NAME_MAP = Arrays.stream(SaleTypeStrEnum.values()).collect(Collectors.toMap(SaleTypeStrEnum::name, Function.identity()));public static SaleTypeStrEnum getByName(String saleTypeStr){return NAME_MAP.get(saleTypeStr);}}
这样每次检索就是O(1)了,那么最终方法体内也能使用switch管理原本的if-else
public static Integer parseSaleType(String saleTypeStr){switch(SaleTypeStrEnum.getByName(saleTypeStr)){case JX:return SaleTypeIntEnum.JX.getCode();// OTHERSdefault:return null;}}

public enum SaleTypeRelEnum {// 不在分别定义两类变量,而是直接定义变量映射关系JX("JX", 1),// OTHERS;private String fromCode;private Integer toCode;private static Map<String, SaleTypeRelEnum> FROM_CODE_MAP = Arrays.stream(SaleTypeRelEnum.values()).collect(Collectors.toMap(SaleTypeRelEnum::getFromCode, Function.identity()));public static SaleTypeRelEnum get(String saleTypeStr){return FROM_CODE_MAP.get(saleTypeStr);}public static Integer parseCode(String saleTypeStr){return Optional.ofNullable(SaleTypeRelEnum.get(saleTypeStr)).map(SaleTypeRelEnum::getToCode).orElse(null);}}
如果将转关系作为枚举,那么从职责上划分,转换这个动作应该是封闭在枚举内的固有行为,而不该暴露在外,故原来对方法的引用其实应该转为对关系枚举中 SaleTypeEnum::parseCode 方法的引用,O(1)检索且封闭性良好,同时支持更多简单单向映射关系的管理,要是以后出现的新场景都是这种关系,那够扛很久嘞。

/*** 定义策略接口*/public interface SaleTypeParseStrategy{Integer parse(SaleTypeParseContext saleTypeParseContext);}/*** 策略实现*/public class JxSaleTypeParseStrategy implements SaleTypeParseStrategy{public Integer parse(SaleTypeParseContext saleTypeParseContext) {return SaleTypeIntEnum.JX.getCode();}}/*** 调用上下文*/public class SaleTypeParseContext{private SaleTypeStrEnum saleTypeStr;private SaleTypeParseStrategy parseStrategy;public Integer pasre(){return parseStrategy.parse(this);}}public static Integer parseSaleType(String saleTypeStr){SaleTypeStrEnum saleTypeEnum = SaleTypeStrEnum.getByName(saleTypeStr);SaleTypeParseContext context = new SaleTypeParseContext();context.setSaleTypeStr(saleTypeEnum);switch(saleTypeStr){// 策略路由case JX:context.setParseStrategy(new JxSaleTypeParseStrategy());break;// 继续扩展default:return null;}return context.parse();}

public static class SaleTypeParseStrategyContainer{public final static Map<SaleTypeStrEnum, SaleTypeParseStrategy> STRATEGY_MAP = new HashMap<>();public void init(){STRATEGY_MAP.put(SaleTypeStrEnum.JX, new JxSaleTypeParseStrategy());// 继续拓展}public Integer parse(SaleTypeParseContext saleTypeParseContext){return Optional.ofNullable(STRATEGY_MAP.get(saleTypeParseContext.getSaleTypeStr())).map(strategy-> strategy.parse(saleTypeParseContext)).orElse(null);}}
容器内手动创建各个策略的实现的单例后进行托管,那调用方只需要去构建上下文就好了,实际调用的方法更换为 SaleTypeParseStrategyContainer::parse,那后续无论策略如何丰富,调用方都不需要再感知这部分变化。后续出现了新的策略实现,则在工厂内继续追加路由表即可。

public interface SaleTypeParseStrategy{Integer parse(SaleTypeParseContext saleTypeParseContext);// 所支持的情况SaleTypeStrEnum support();}public class JxSaleTypeParseStrategy implements SaleTypeParseStrategy{public Integer parse(SaleTypeParseContext saleTypeParseContext) {return SaleTypeIntEnum.JX.getCode();}public SaleTypeStrEnum support() {return SaleTypeStrEnum.JX;}}public static class SaleTypeParseStrategyContainer{public final static Map<SaleTypeStrEnum, SaleTypeParseStrategy> STRATEGY_MAP = new HashMap<>();private List<SaleTypeParseStrategy> parseStrategyList;public void init(){parseStrategyList.stream().forEach(strategy-> STRATEGY_MAP.put(strategy.support(), strategy));}public Integer parse(SaleTypeParseContext saleTypeParseContext){return Optional.ofNullable(STRATEGY_MAP.get(saleTypeParseContext.getSaleTypeStr())).map(strategy-> strategy.parse(saleTypeParseContext)).orElse(null);}}

public interface SaleTypeParseStrategy{Integer parse(SaleTypeParseContext saleTypeParseContext);// 用于判断是否支持boolean support(SaleTypeParseContext saleTypeParseContext);}public class JxSaleTypeParseStrategy implements SaleTypeParseStrategy{public Integer parse(SaleTypeParseContext saleTypeParseContext) {return SaleTypeIntEnum.JX.getCode();}public boolean support(SaleTypeParseContext saleTypeParseContext) {return SaleTypeStrEnum.JX.equals(saleTypeParseContext.getSaleTypeStr());}}public static class SaleTypeParseStrategyContainer{private List<SaleTypeParseStrategy> parseStrategyList;public Integer parse(SaleTypeParseContext saleTypeParseContext){return parseStrategyList.stream().filter(strategy->strategy.support(saleTypeParseContext)).findAny().map(strategy->strategy.parse(saleTypeParseContext)).orElse(null);}}
- 植入Diamond走走动态配置开关的思路;
- 植入QLExpress搞搞逻辑表达式的思路;
- 把策略实现改成HsfProvider走分布式调用思路;
- 借助一些成熟的网关走服务路由的的调用思路;
 微信赞赏
微信赞赏 支付宝扫码领红包
支付宝扫码领红包
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。侵权投诉:375170667@qq.com
       
       
                








