我有一个枚举类,它的值应该随时间增长,我希望添加新枚举值的用户也在某处提供实现。但我不知道如何迫使他们提供弹劾,因为弹劾将在其他类。例如。
public enum DayType {
SUNDAY,
MONDAY;
}
在课堂上介绍
class X{
DateType dateType;
..
}
在别的班级里用过
if (x.getDateType().equals(DayType.SUNDAY)) {
...
}else if(x.getDateType().equals(DayType.MONDAY)){
..
}
因此,如果有人添加了datetype,那么他应该被迫在上面的if-else逻辑中添加impement。如果可能的话,最好增加功能接口?
我不能在枚举类中强制执行,因为该执行具有spring依赖项。
8条答案
按热度按时间gojuced71#
我认为你在编译时没有选择来执行你的策略。我建议创建一个接口(类似
DateTypeAction
)使用单一方法(例如action()
)然后是一个工厂,它根据您的DateType
(类似于DateTypeActionFactory.getDateTypeAction(DateType dateType)
). 在初始化阶段,可以运行datetype的所有值(DateType.values()
)并检查DateTypeAction
在你的DateTypeActionFactory
对于每个值。如果发现一个或多个值缺少实现,则抛出一个异常,并显示一条错误消息,告诉您缺少实现,并且无法启动应用程序。这似乎是一个合理的模式。顺便说一句,如果您使用这种模式,我有一个建议:我编写了一个名为mgntutils的开源java库,它提供了一个简单的框架(非常适合与spring一起使用),该框架具有自填充工厂模式。i、 您可以创建一个接口和一个工厂扩展库提供的父类,然后您的接口的每个实现将自动插入到您的工厂预定义的名称。我用了很多次,觉得很方便。下面是描述整个库的文章的链接:mgntutils开源java库,具有堆栈跟踪过滤、静默字符串解析、unicode转换器和版本比较。查找段落
生命周期管理(自示例化工厂)
对于功能的简短解释。在这里,您可以了解该特性的全部思想:在springframework中对“孤立”bean的非侵入式访问。这两篇文章也解释了从何处获取库,但这里有直接的链接:maven中央存储库和github。该库附带了编写良好的javadoc
niwlg2el2#
尽管我怀疑这在编译时会受到限制。实现类似功能的一种可能更简洁的方法是使用
switch
在这里:ifmq2ha23#
真正的答案是:不要这样做。
如果您有一些“类型”,并且您知道随着时间的推移,这个“类型”将看到新的化身,需要不同的行为,那么答案就是使用抽象类和多态性。
不管您使用if/else链还是switch语句:您的想法是:
这是坏习惯!
如果有的话,您应该在工厂中使用这样的switch语句来返回不同的子类示例,然后对这些对象调用“common”方法。
您当前的方法是a)外部化关于内部状态的知识,b)以多种方式强制依赖关系。
这就是意大利面代码的开始!最好退一步,考虑更多的面向对象的方法来解决这个问题!
t3irkdon4#
枚举是用来保存编译时(静态)最终值的,所以动态地添加更多的值是不可能的(只是把它放在那里)。至于问题的另一部分,正如@nullpointer所指出的,最好使用
switch
条款。除了提高代码清晰度外,如果存在没有case
为它们声明的语句(即default
)qij5mzcb5#
nullpointer选项的另一种选择是将该逻辑放在enum本身中,假设这在您的设计中是有意义的(如果该责任可以由day类型enum承担)。
这将确保提供特定于某一天的实现的需求对于更改
DayType
.打电话的人只需要:
xmq68pz96#
可以创建一个接口,该接口将由枚举类实现。在这种情况下,所有枚举都必须在接口中实现方法。
i2byvkas7#
我也不确定按用户设计扩展枚举是否是个好主意。它是静态的,正如@garikai所说。这将导致代码气味。
如果你想有一个简单的选项,扩展Map从枚举到函数我会建议
Map<DateType, Function> map = new EnumMap<DateType, Function>(DateType.class);
然后使用getOrDefault
以确保您将获得任何输出。pod7payv8#
这个答案扩展了其他一些促进多态性使用的答案。
为了避免在某个地方出现every growing switch/conditional,我通常会在接口中添加一个标识方法:
然后我用所有可用的
DayProcessor
spring引入的实现:这是战略模式的一种形式。
列出所有日期的另一种方法是枚举它们(但在创建新的日期时,必须更新列表):