Java多枚举重复方法抽离、按族获取及枚举接口应用咨询
解决方案
枚举可以实现接口,通过定义公共接口统一抽象方法,再配合泛型工具方法、类扫描机制就能同时解决你提到的两个优化问题,具体实现步骤如下:
第一步:定义公共消息枚举接口
把所有消息枚举类共有的属性方法抽象成接口,后续所有模块的消息枚举都实现该接口:
public interface IModuleMessage { // 统一抽象多语言内容获取方法 String getMessageEN(); String getMessageES(); // 枚举自带name()方法,无需额外抽象,使用时可直接调用 }
第二步:改造原有枚举类实现接口
删除两个模块枚举类中重复的getMessagesAndCodes静态方法,仅保留基础属性、构造方法和接口实现即可:
public enum Module1Messages implements IModuleMessage { MOD1_MESSAGE_1("Message 1 for module 1", "Mensaje 1 para modulo 1"); private final String message_en; private final String message_es; Module1Messages(String msgCodeEn, String msgCodeEs) { this.message_en = msgCodeEn; this.message_es = msgCodeEs; } @Override public String getMessageEN() { return this.message_en; } @Override public String getMessageES() { return this.message_es; } } // Module2Messages按相同规则改造即可 public enum Module2Messages implements IModuleMessage { MOD2_MESSAGE_1("Message 1 for module 2", "Mensaje 1 para modulo 2"); private final String message_en; private final String message_es; Module2Messages(String msgCodeEn, String msgCodeEs) { this.message_en = msgCodeEn; this.message_es = msgCodeEs; } @Override public String getMessageEN() { return this.message_en; } @Override public String getMessageES() { return this.message_es; } }
第三步:编写通用工具方法解决重复代码问题
把原来重复的getMessagesAndCodes逻辑抽成通用泛型工具方法,支持传入任意实现了IModuleMessage接口的枚举类,自动生成对应JSON数组:
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; public class MessageEnumUtils { // 通用获取单个模块消息列表的方法 public static <T extends Enum<T> & IModuleMessage> JSONArray getMessagesAndCodes(Class<T> enumClazz) { JSONArray jArr = new JSONArray(); // 获取目标枚举类的所有枚举项 T[] allEnums = enumClazz.getEnumConstants(); for (T curMsgCode : allEnums) { JSONObject jObj = new JSONObject(); jObj.put("message_code", curMsgCode.name()); jObj.put("English", curMsgCode.getMessageEN()); jObj.put("Spanish", curMsgCode.getMessageES()); jArr.add(jObj); } return jArr; } }
第四步:动态扫描枚举族解决硬编码问题
通过包扫描机制自动收集指定路径下所有消息枚举,无需手动硬编码枚举列表:
import org.reflections.Reflections; public JSONArray getAllModuleMessages() { JSONArray jArr = new JSONArray(); // 扫描指定包下所有实现了IModuleMessage的类,替换为你自己的枚举类所在包路径 Reflections reflections = new Reflections("com.yourproject.message.enums"); var allMessageEnums = reflections.getSubTypesOf(IModuleMessage.class); for (Class<? extends IModuleMessage> enumClazz : allMessageEnums) { // 过滤掉非枚举的实现类 if (enumClazz.isEnum()) { jArr.add(MessageEnumUtils.getMessagesAndCodes((Class<? extends Enum>) enumClazz)); } } return jArr; }
补充说明
上面用到的Reflections是第三方类扫描工具,如果你不想引入额外依赖,也可以自己通过ClassLoader遍历指定路径下的类文件,判断类是否实现了IModuleMessage接口即可。如果不需要完全动态,也可以把所有枚举类放到一个静态集合里统一维护,相比原来逐行add的方式也更易维护。
内容的提问来源于stack exchange,提问作者Fran Gómez
相关产品推荐
相关产品推荐

