枚举内部的逻辑
我和我的同事正在讨论枚举中的逻辑。我个人的偏好是 Java 枚举中不有任何类型的逻辑(尽管 Java 提供了这样做的能力)。本例中的讨论集中在枚举内部有一个返回地图的便捷方法:
public enum PackageType {
Letter("01", "Letter"),
..
..
Tube("02", "Packaging Tube");
private String packageCode;
private String packageDescription;
..
..
public static Map<String, String> toMap() {
Map<String, String> map = new LinkedHashMap<String, String>();
for(PackageType packageType : PackageType.values()) {
map.put(packageType.getPackageCode(), packageType.getPackageDescription());
}
return map;
}
}
我个人的偏好是将其提取到服务中。将方法放在枚举中的争论主要是为了方便。这个想法是,您不必去服务来获取它,而是可以直接查询枚举。
我的论点集中在关注点分离和将任何类型的逻辑抽象为服务。我不认为“方便”是将此方法放入枚举中的有力论据。
从最佳实践的角度来看,哪一个更好?或者这仅仅是个人喜好和代码风格的问题?
My colleagues and I were having a discussion regarding logic in enums. My personal preference is to not have any sort of logic in Java enums (although Java provides the ability to do that). The discussion in this cased centered around having a convenience method inside the enum that returned a map:
public enum PackageType {
Letter("01", "Letter"),
..
..
Tube("02", "Packaging Tube");
private String packageCode;
private String packageDescription;
..
..
public static Map<String, String> toMap() {
Map<String, String> map = new LinkedHashMap<String, String>();
for(PackageType packageType : PackageType.values()) {
map.put(packageType.getPackageCode(), packageType.getPackageDescription());
}
return map;
}
}
My personal preference is to pull this out into a service. The argument for having the method inside the enum centered around convenience. The idea was that you don't have to go to a service to get it, but can query the enum directly.
My argument centered around separation of concern and abstracting any kind of logic out to a service. I didn't think "convenience" was a strong argument to put this method inside an enum.
From a best-practices perspective, which one is better? Or does it simply come down to a matter of personal preference and code style?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
嗯,我以前做过这件事,但这当然并不意味着这是“最好”的事情。
不过,从我的角度来看,我更愿意在枚举上使用这种逻辑,出于同样的原因,您不会将“toString”方法移出到服务中。逻辑仅涉及枚举本身及其自身的表示。
我认为将这样的方法移到服务中会产生误导 - 通过将其放在枚举上,您就可以提前了解枚举具有“toMap”方法的事实。不了解该服务并且只是查看枚举的人可能不知道这一点。
它还有助于 IDE 中的自动完成 - 我可以点击“.”键并立即查看该对象提供的方法。
Well, I've done this before but that certainly doesn't mean it's the 'best' thing to do.
From my perspective, though, I would prefer to have that logic on the enum, for the same reason you wouldn't move a 'toString' method out to a service. The logic only concerns the enum itself, and its own representation.
I think it would be misleading to move such a method out to a service - by placing it on the enum you are being up front about the fact that the enum has a 'toMap' method. Someone who didn't know about the service and was just looking at the enum may not know that.
It also helps with auto completion in IDE's - I can hit the '.' key and instantly see methods provided by the object.
我认为这可能取决于个人喜好以及你是否认为逻辑将来可能会改变。
枚举逻辑的最佳用例(因为它非常静态)是用于不会改变的事物。 java.util.concurrent.TimeUnit 中的逻辑就是一个很好的例子:时间单位之间的转换因子是明确定义的并且永远不会改变,因此它是静态逻辑的良好候选者嵌入枚举中。
I think it probably comes down to personal preference and whether or not you think the logic might change in the future.
The best use case for enum logic (since it's pretty static) is for things that aren't going to change. The logic in
java.util.concurrent.TimeUnit
is a pretty good example of this: the conversion factors between time units are well-defined and won't ever change, so it's a good candidate for static logic to embedded within the enum.我看不出有任何有说服力的理由来解释为什么做你所建议的事情是“好的做法”……或“坏的做法”……。
我倾向于以方便为理由。但坦率地说,这不是那种花很多时间争论的事情......在我看来。
I cannot see any persuasive reason why it is "good practice" ... or "bad practice" ... to do what you are suggesting.
I'm inclined to go for the convenience argument. But frankly, this is not the kind of thing that it is productive to spend man-days debating ... IMO.
我已经尝试过枚举中的逻辑几次,但我唯一真正高兴的是:
通常,一旦您开始添加实例变量/方法,您可能应该使用适当的类来做一些事情。
I have tried logic in enums a few times, but the only thing I am ever really happy about is something like:
Generally once you start adding instance variables/methods you should probably be doing something with a proper class.
我首先将其放入枚举中。如果系统中只有一个 toMap() 方法,那么额外的类肯定是不必要的,而且会很烦人。
如果我有一堆枚举,我想从中创建这样的映射,或者可能预见到这种情况,那么我将创建一个静态实用程序类和一个通用实用程序方法来执行此操作。
我个人的看法是,实践胜过理论。
编辑:哦等等,这很难提供一个通用的实用方法。在这种情况下,如果该方法是特定于枚举的,我肯定会把它放在枚举中。如果我是维护程序员,如果你有一个我必须寻找的额外课程,我会非常不满意。
I'd start with putting it in the enum. If there will be only one toMap() method in the system, having an extra class is surely unnecessary and will be annoying.
If I had bunch of enums from which I want to create such map, or maybe anticipate such situation, THEN I'll create a static utility class, and a generified utility method to do that.
My personal opinion is, practicality tramps theory.
EDIT: Oh wait, this would be difficult to provide a generic utility method for.. In that case, if the method is going to be that enum specific, I'd definitely go with putting it in the enum. If I were the maintenance programmer, I'd be very dissatisfied if you would have an extra class that I have to look for.
就像任何取决于用途的事情一样,有一般规则,但实用性始终应该赢得争论。地图是用来做什么的?您是否需要限制地图的内容,例如,如果地图用于填充组合框,是否需要删除某些选项,例如,如果某些承运商仅处理某些包裹类型,则可以使用策略来填充地图,最好在枚举之外完成。
尽管如此,我更倾向于在其他地方创建地图,这种额外的间接级别永远不会妨碍灵活性,并且可以节省很多痛苦,并且现在增加很少的开销。您还可以对其进行编码,以便获得与其他枚举类似的功能。
Like anything it would depend on the usage, there are general rules but practicality should always win the argument. What is the map used for? Would you ever need to restrict the contents of the map, e.g. if the map is used to populate a combo box, is there ever the need to remove some choices, say if some carriers only handled certain package types a strategy could be used to populate a map, that would be best done outside of the enum.
Despite that, my preference would be to have a create the map elsewhere, that extra level of indirection is never a hindrance to flexibility and could save a lot of grief and adds little overhead now. And you can also code it so you can get similar functionality with other enums.