在枚举内部提供功能是否被视为“干净”? [英] Is providing a function inside of an enum considered "clean"?

查看:81
本文介绍了在枚举内部提供功能是否被视为“干净”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在源代码中发现了一些代码,这些代码基本上使用开关大小写来遍历枚举的每个可能值,并调用适当的函数,该函数根据数据类型返回Number对象。

I found some code in a source that basically uses a switch case to go through every possible value of an enum and call the appropriate function that returns a Number object based on the data type.

这是一个代码段:

case TYPE_16BIT_SIGNED_BE:
    measurement = response.getRegisters().getShort(0);
    break;
case TYPE_16BIT_UNSIGNED_BE:
    measurement = response.getRegisters().getUnsignedShort(0);
    break;
case TYPE_16BIT_SIGNED_LE:
    measurement = response.getRegisters().getShortLE(0);
    break;

现在我的问题是,将其添加到枚举本身被认为是好还是坏做法?

Now my question is, is adding this to the enumeration itself considered to be a good or a bad practice?

以下是我的意思的示例:

Here is an example of what I mean:

public enum SomethingType {
    INT((b) -> {
        return b.getInt(0);
    }),
    DOUBLE((b) -> {
        return b.getDouble(0);
    }),
    LONG((b) -> {
        return b.getLong(0);
    });

    private Function<ByteBuf, Number> getNumber;

    SomethingType(Function<ByteBuf, Number> getNumber) {
        this.getNumber = getNumber;
    }
}


推荐答案

一个可以找到推广的这种方法 地点,一个可能有说服力的示例是状态机。枚举成员在 Scala语言中也被采用。因此,它显然不是Java的怪胎功能,而是一种有用的实用功能。我亲自在生产代码中反复使用它,尤其是在需要从枚举到值或从枚举到函数的静态映射时。

One can find this approach promoted on all kind of places, a likely defensible example are state machines. Enum members were also adopted much later in the Scala language. So it clearly was no freak feature of Java but a desired one which proved to be useful. I personally used it in production code time and again, especially when some static mapping was needed, from enum to value or from enum to function. It allows for tightly structured, concise code.

此外,IMO令人信服地表明,使用lambdas的方法比使用覆盖方法更适合使用第一个问题中介绍的方法可以从> @ johannes-kuhn提供的链接中稍作清除。

Furthermore IMO it has been convincingly shown that the usage of lambdas the way presented in the initial question is preferable over the use of overridden methods, if I may scavenge a bit from the link provided by @johannes-kuhn.

因此,我确实认为这是一种很好的做法(干净(在M.Fowler和R.Martin的意义上),而不是坏的。

也就是说,这里有一些持久的注释,其中将枚举视为不干净,因为它们诱使您使用不干净的开关语句(准确地说:a代码气味,也许与干净的相反),指的是M.Fowlers的第一版 重构:改进现有代码的设计。而且,您知道的是,他创造了清洁一词。 (和代码气味)。但在 2005年版他撤回了这一判断。

That said, there are persistent comments out there which consider enums as such not to be clean, due to the fact that they lure you into using switch-statements, which are not clean (precisely: a code smell, perhaps the opposite of clean), referring to M.Fowlers first edition of "Refactoring: Improving the Design of Existing Code". And, you know, it was him who coinded the term "clean" (and "code smell"). But in the 2005 edition he retracted this judgement.

关于转换:必须考虑扩展枚举时会发生什么,而忘了扩展所有也切换。我和我的同事们发现引入单元测试非常有用,该单元测试遍历枚举的所有项目并进行测试,需要确保什么。该问题为lambdas增强的Enums带来了另一个论点:在某些情况下,您可以保留开关( switch someValue ... case Enum.x:dosmthg()),而赞成调用映射函数( someValue.dosmthg())。

As for the switches: one has to consider what happens when you extend the Enums and forget to extend all switches too. Me and my collegues found it useful to introduce unit tests, that looped through all items of the enum and tested, what was needed to be ensured. That issue yields another argument for Enums enhanced by lambdas: you can spare the switches in some cases (switch someValue ... case Enum.x: dosmthg()) in favor of calling the mapped function (someValue.dosmthg()).

至于建议将此问题包含在表达问题

As for the suggestion to subsume this question under the Expression Problem:

经过仔细检查,它看起来就像表达问题完全与问题有关。从链接:表达式问题是旧问题的新名称。目的是通过案例来定义一种数据类型,其中可以在不重新编译现有代码的情况下,又可以在保持静态类型安全性(例如,不强制转换)的情况下,向数据类型添加新案例并在该数据类型上添加新功能。 $ c>

Under close examination it doesn't look like the Expression Problem is related to the question at all. From the link: "The Expression Problem is a new name for an old problem. The goal is to define a datatype by cases, where one can add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety (e.g., no casts)."

因此,不能像建议的那样具有方法A和方法B 的表达问题,这与不能具有 Hadwiger-Nelson问题。表达问题本身就是一个问题,也是功能性和面向对象语言的困惑者,每种语言都有各自不同的解决方案,与此处给出的上下文无关。这是显示的Java解决方案,声称完整和有效,以及Haskell解决方案。十分棘手的复杂事情。

Therefore one can not have the Expression Problem with approach A and approach B like suggested, the same way one can not have the Hadwiger–Nelson problem with them. The Expression Problem is a problem in its own right and a puzzler for functional and object oriented languages, with distinct solutions in each of them, independent from a context like given here. Here's a java solution shown that claims to be both complete and valid, alongside a Haskell solution. Quite a complex thing acutally.

这篇关于在枚举内部提供功能是否被视为“干净”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆