Считается ли предоставление функции внутри перечисления «чистым»? - PullRequest
3 голосов
/ 04 октября 2019

Я нашел некоторый код в источнике, который в основном использует регистр переключателя, чтобы просмотреть каждое возможное значение перечисления и вызвать соответствующую функцию, которая возвращает объект Number на основе типа данных.

Вотфрагмент:

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;

Теперь мой вопрос: добавление этого к самому перечислению считается хорошей или плохой практикой?

Вот пример того, что я имею в виду:

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;
    }
}

1 Ответ

2 голосов
/ 05 октября 2019

Этот подход можно продвигать на всех местах , вероятным оправданным примером являются конечные автоматы . Члены Enum были также приняты намного позже на языке Scala . Так что, очевидно, это была не странная особенность Java, а желанная, которая оказалась полезной. Я лично использовал его в производственном коде снова и снова, особенно когда требовалось некоторое статическое отображение, от enum к значению или от enum к функционированию. Он допускает плотно структурированный, лаконичный код.

Кроме того, в IMO было убедительно показано, что использование лямбд, описанное в первоначальном вопросе, предпочтительнее, чем использование переопределенных методов, если я могу немного убрать из ссылка, предоставленная @ johannes-kuhn .

Поэтому я утверждаю, что это считается хорошей практикой ( "чистый" в смысле М. Фаулер и Р.Мартин) а не плохой. И если это явно не считается, это должно быть.

Тем не менее, существуют постоянные комментарии, которые считают перечисления как таковые не чистыми , в связи с тем, чточто они заманивают вас использовать операторы switch, которые не являются чистыми (точнее: запах кода, возможно, противоположный чистому), ссылаясь на первое издание M.Fowlers « Рефакторинг: улучшение дизайна существующего кода ». И, вы знаете, именно он назвал термин «чистый» (и «кодовый запах»). Но в выпуске 2005 он отказался от этого суждения.

Что касается переключателей: нужно учитывать, что происходит, когда вы расширяете Enums, и забывает расширять также все переключатели. Я и мои коллеги сочли полезным ввести юнит-тесты, которые прошли все пункты перечисления и протестировали, что необходимо было обеспечить. Эта проблема приводит к еще одному аргументу для Enums, усиленному лямбдами: в некоторых случаях вы можете сэкономить переключатели (switch someValue ... case Enum.x: dosmthg()) в пользу вызова сопоставленной функции (someValue.dosmthg()).

Что касается предложения включить этовопрос по Проблема выражения :

При внимательном рассмотрении не похоже, что проблема выражения связана с рассматриваемым вопросом. По ссылке: "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. Довольно сложная вещь.

Убей меня, если я ошибаюсь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...