代码之家  ›  专栏  ›  技术社区  ›  user1884155

将Java枚举值链接到动态实例化的对象

  •  1
  • user1884155  · 技术社区  · 5 年前

    我的Java 8应用程序中有一种代码味道,我想通过一些重新设计来解决。

    我已经声明了一个枚举 DataType 它不仅包含枚举值,还包含基于某些逻辑的这些枚举值的有序列表。总之,每个枚举值都声明了一组对其他枚举值(相同类型)的依赖关系,列表是一个 topologically sorted list 这些枚举值中的一个。每个枚举值也有一个 Calculator 与之相关。

    public Enum DataType
    {
        A(EnumSet.noneOf(DataType.class), new CalculatorA()),
        B(EnumSet.of(A), new CalculatorB()),
        C(EnumSet.noneOf(DataType.class), new CalculatorC()),
        D(EnumSet.Of(A,B,C), new CalculatorD()),
        ... more ...
    
        ...constructor and attributes...
    
        public static final List<DataType> DATA_TYPES_SORTED_BY_DEPENDENCIES;
    
        static
        {
            DATA_TYPES_SORTED_BY_DEPENDENCIES = ...
        }
    }
    

    我知道枚举是自然有序的(有序的),因此,通过以正确的顺序声明它们,就不需要进行任何排序。但是,枚举值的数量很大,可能会随着时间的推移而变化。我不想自己承担维护正确顺序的负担,如果我只是声明依赖项,我希望程序能帮我做到这一点。它也是自我解释的代码,因为它明确地提到了cetain依赖项的存在,并且它们是经过排序的。

    我的程序的目标是以正确的顺序在一组记录上运行计算器,因此为什么要对枚举进行排序:

    for(Record r : records)
    {
        for(DataType type : DataType.DATA_TYPES_SORTED_BY_DEPENDENCIES)
        {
            Integer result = type.getCalculator().calculate(r);
            r.getDataMap().put(type, result);
        }
    } 
    

    这个设置一直正常运行,直到有一个需求出现,即计算器(过去在enum类中静态实例化)应该是可参数化的。参数将来自webservice或数据库调用。我得恢复正常生活 计算器 类,我现在已经失去了枚举类型和计算器之间的链接。

    为了解决这个问题,我创建了一个HashMap,以便于检索:

        ...get some parameters from another service...
    
        Map<DataType, Calculator> calculatorsByTypeMap = new HashMap<>(400);
    
        calculatorsByTypeMap.put(DataType.A, new CalculatorA(someParameterA));
        calculatorsByTypeMap.put(DataType.B, new CalculatorB());
        calculatorsByTypeMap.put(DataType.C, new CalculatorC(someParameterC1, somereParameterC2));
        calculatorsByTypeMap.put(DataType.D, new CalculatorD(someParameterD));
        ...
    
        return calculatorsByTypeMap;
    

    这让我很困扰,因为我在概念上声明了两次(相当大的)枚举:一次用于排序逻辑,一次用于与计算器的链接。有没有办法防止这种情况发生?

    0 回复  |  直到 5 年前
        1
  •  0
  •   Ray Tayek    5 年前

    使用空计算器字段生成枚举。在运行时,进行拓扑排序并构建排序列表。获取新计算器并在枚举中设置计算器值。