Огромный ли оператор, рефакторинг с использованием Enum или Map? - PullRequest
1 голос
/ 12 марта 2020

Я наткнулся на 400 строк, если / иначе, с около 100 предложений в нем. Так что я чувствую потребность реорганизовать этого монстра.

Метод имеет такую ​​форму:

private void updatePaymentField(Payment payment, String fieldName, String value) {
    if (Field.FIELD_1.equalsIgnoreCase(fieldName)) {
        payment.getField1().setId(value)

    } else if (Field.FIELDS_2.equalsIgnoreCase(fieldName)) {
        payment.setField2(valueToSet)

    } else if (Field.FIELDS_3.equalsIgnoreCase(fieldName)) {
        UtilClass::setField3(payment, value)

    } else if ... // 100 more of these

}

Я изменил это на enum, который принимает String (имя поля ) и BiConsumer<Payment, String> (метод / лямбда, который обновит поле платежа)

enum Field {
    UNDEFINED("", null),

    FIELD1(Fields.FIELD1, (Payment, value) -> payment.getField1().setId(value)),
    FIELD2(Fields.FIELD2, Payment::setField2),
    FIELD3(Fields.FIELD3, UtilClass::setField3),
    // 100 more of these, 

    private String fieldName;
    private BiConsumer<Payment, String> populateFunction;

    Field(String fieldName, BiConsumer<Payment, String> populateFunction) {
        this.fieldName = fieldName;
        this.populateFunction = populateFunction;
    }

    public static Field getByName(String name) {
        return Arrays.stream(values())
                .filter(p -> p.getFieldName().equals(name))
                .findFirst()
                .orElse(UNDEFINED);
    }

    private String getFieldName() {
        return fieldName;
    }
    public BiConsumer<Payment, String> getPopulateFunction() {
        return populateFunction;
    }
}

, тогда в основном большой if можно заменить на

private void updatePaymentField(Payment payment, String fieldName, String value) {
    Field field = Field.getByName(fieldName);
    if(field != Field.UNDEFINED) {
        field.getPopulateFunction().accept(payment, value);
    }
}

, который работает и все хорошо, но я думаю, что я мог перестараться, он может достичь того же с помощью простого Map

Map<String, BiConsumer<Payment, String>> fieldMap = new HashMap<>();
fieldMap.put(Fields.FIELD1, (Payment, value) -> payment.getField1().setId(value))
fieldMap.put(Fields.FIELD2, Payment::setField2)
fieldMap.put(Fields.FIELD3, PaymentUtilClass::setField3)
// 100 more of these, 

и использовать его таким же образом

private void updatePaymentField(Payment payment, String fieldName, String value) {
    BiConsumer<Payment, String> populateFunction = fieldMap.get(fieldName);
    if(populateFunction!=null) {
        populateFunction.accept(payment, value);
    }
}

Я чувствую, что доступ к BiConsumer<Payment, String> будет быстрее при использовании Map, чем при использовании метода getByName в enum, и запись Map также будет легче. Поэтому я думаю, что Map может быть лучшим выбором.

Таким образом, вопрос заключается в следующем: перед тем, как изменить это значение на Map, есть ли какая-либо объективная ценность в использовании en enum вместо Map в этом конкретном c сценарии использования?

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