代码重构系列|代码重构之枚举使用(策略模式思想)

前言

目前项目是为服务的架构,进行业务的拆分,但是服务之间的交互使用的是http->RestTemplate的方式,这样的方式就没办法像rpc那样通过接口的方式进行直接调用,这个需要单独对调用的地址路径进行定义。
比如订单的创建方法url:http://域名/模块名/order/create(http://order-provider/order-api/stock/sub),库存的扣减方法url:http://域名/模块名/order/create(http://stock-provider/stock-api/stock/sub);
项目中平常我们定义变量值,一般都是定义一个Constants类,目前项目也不例外,定义了一个URLConstants类,里边存放的就是各个维服务模块的请求路径,如下:
public class URLConstants { /** * -----------------订单系统------------------- */ //订单模块服务的域名信息 public static final String ORDER_URL = CommonUrlConfig.getProperty("order.server.url"); public static final String ORDER_CREATE_URL = ORDER_URL + "/order/create"; public static final String ORDER_FIND_URL = ORDER_URL + "/order/find"; /** * ---------------------------库存系统---------------- */ //库存模块服务的域名信息 public static final String STOCK_URL = CommonUrlConfig.getProperty("stock.server.url"); public static final String STOCK_CREATE = STOCK_URL + "/stock/create"; public static final String STOCK_FIND = STOCK_URL + "/stock/find"; ...... ...... ...... }

调用的时候就URLConstants.ORDER_CREATE_URL,这样的方式指定
httpClient.get(URLConstants.ORDER_CREATE_URL, params, AResponse.class);

以上就是目前项目的现状,这样的方式,给人的第一感觉就是代码太堆砌,虽然也能用,但是这样的写法感觉还是有点low,因为所有的业务都放到一起了,并且注释的方式也不好,有的甚至也不加,刚工作时候可以这样写,现在的水平看到这样的方式,有点不能忍,稍微改动下吧。
思路 【代码重构系列|代码重构之枚举使用(策略模式思想)】思路其实很简单,我想借助枚举的方式进行重构,把URLConstants进行拆解,按微服务模块进行重新定义, 但是因为每个微服务模块的域名是不一样的,就比如上边类中的写法CommonUrlConfig.getProperty(“stock.server.url”); 我是通过定义一个枚举接口,面向接口的思想,对这一步的获取进行处理;
/** * 整合-外部请求路径接口 */ public interface HttpUrlEnum {/** * url请求路径 * @return */ public String getHttpUrl(); }

其他枚举对该枚举进行实现,重写该方法,比如拆分后订单的url定义如下:
public enum OrderUrlEnum implements HttpUrlEnum {ORDER_CREATE_URL( "/order/create", "订单新增"), ORDER_FIND_URL( "/order/find", "订单更新");//将这样直接的方式使用接口的实现getHttpUrl()来获取,对策略模式加深理解--枚举的本质也是抽象接口 //private static final String ORDER_URL = CommonUrlConfig.getProperty("order.server.url"); private String url; private String desc; OrderUrlEnum(String url, String desc) {this.url = url; this.desc = desc; }public String getUrl() {return getHttpUrl()+url; }public void setUrl(String url) {this.url = url; }public String getDesc() {return desc; }public void setDesc(String desc) {this.desc = desc; }@Override public String getHttpUrl() {return CommonUrlConfig.getProperty("order.server.url"); } }

库存跟订单的实现一样,这样的方式就很直白了,业务调用进行了隔离,各自重新定义实现接口,描述信息也完善,后边人再看到这个也会很清晰明了;
总结 最后关于枚举的其他信息,比如枚举只能实现而不能继承,枚举的本质这些就不在这说明了,网上的资料很多,大家可以自行搜索理解。
枚举本质上是通过普通的类来实现的,只是编译器为我们进行了处理。每个枚举类型都继承自java.lang.Enum,并自动添加了values和valueOf方法。而每个枚举常量是一个静态常量字段,使用内部类实现,该内部类继承了枚举类。所有枚举常量都通过静态代码块来进行初始化,即在类加载期间就初始化。另外通过把clone、readObject、writeObject这三个方法定义为final的,同时实现是抛出相应的异常。这样保证了每个枚举类型及枚举常量都是不可变的。可以利用枚举的这两个特性来实现线程安全的单例。
参考文章:https://blog.csdn.net/mhmyqn/article/details/48087247

    推荐阅读