Рефакторинг множественного числа if if / else if с проверками null более элегантно - PullRequest
0 голосов
/ 05 июня 2019

У меня есть кратное число if if if, которое выполняет нулевую проверку внутри блока try / catch.Я знаю, что есть лучший способ реорганизовать его, но в недоумении, учитывая, что я новичок в Java 8 (немного смущает).

Мой блок if else

Я пытался использовать Optional.ofNullable, но без vail

try {
                if (this.oldInvestigator != null) {
                    if (this.oldInvestigator.getId() == null && this.newInvestigator.getId() != null) {
                        someService.sendEmailToInvestigator(newInvestigator);

                    } else if (this.oldInvestigator.getId() != null && this.newInvestigator.getId() != null) {
                        someService.updateInvestigator(this.oldInvestigator, this.newInvestigator);

                    } else {
                        someService.sendNotificationToLeader();
                    }
                }
}

В моем файле классов Java есть другие условия, подобные этому (любезно предоставленоиз моих предшественников).Я хочу реорганизовать их наилучшим образом либо с помощью Java 8, либо с помощью общей реализации проекта

Ответы [ 4 ]

0 голосов
/ 05 июня 2019

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

new Action<>(oldInvestigator, newInvestigator)
  .orExecute((o, n) -> o.getId() == null && n.getId() != null, (o, n) -> someService.sendEmailToInvestigator(n))
  .orExecute((o, n) -> o.getId() != null && n.getId() != null, someService::updateInvestigator)
  .orExecute((o, n) -> true,                                   (o, n) -> someService.sendNotificationToLeader());

и вот как Action выглядит так:

class Action<T1, T2> {
    private T1 o1;
    private T2 o2;
    private boolean done;

    //all args private constructor
    //two args public constructor    

    Action<T1, T2> orExecute(BiPredicate<T1, T2> biPredicate, CheckedBiConsumer<T1, T2> biConsumer) throws Exception {
        if(!done && biPredicate.test(o1, o2)) {
            biConsumer.accept(o1, o2);
            return new Action<>(o1, o2, true);
        }
        return this;
    }
}
0 голосов
/ 05 июня 2019

Вы можете сделать его немного более читабельным, инвертировав нулевые проверки и вернув его немедленно.

try {
    if (this.oldInvestigator == null) {
        return;
    }
    if (this.oldInvestigator.getId() == null && this.newInvestigator.getId() != null) {
        someService.sendEmailToInvestigator(newInvestigator);

    } else if (this.oldInvestigator.getId() != null && this.newInvestigator.getId() != null) {
        someService.updateInvestigator(this.oldInvestigator, this.newInvestigator);

    } else {
        someService.sendNotificationToLeader();
    }
}

Однако на самом деле это не проблема. Проблема в том, что вам нужно переосмыслить свой подход. Не идеально использовать нулевые проверки для определения определенного пути в вашем коде. Спросите себя, почему oldInvestigator.getId () должен когда-либо возвращать null. Стоит ли вместо этого указывать Id при создании объекта oldInvestigator? Постарайтесь подумать о том, как вы можете изменить фундаментальный дизайн, вместо того, чтобы попытаться увидеть, как вы можете сделать его лучше при проверке значений.

0 голосов
/ 05 июня 2019

Наверное, так будет лучше.В этом примере кода и OldInvestigator, и NewInvestigator ссылаются на один и тот же класс;

package stackoverflow;

import java.util.Optional;


    public class OldInvestigator
    {

        //id is optional
        private Optional<String> id;

        public Optional<String> getId()
        {
            return id;
        }

        public void setId(String id)
        {
            this.id = Optional.of(id);
        }

    }

Теперь можно определить в вспомогательном классе или другом сервисе (обеспечить повторное использование) такую ​​логику (ниже только для справки, переименовать, переместить& настроить на основе вашей бизнес-логики)

package stackoverflow;

import java.util.Optional;

public class Processor
{

    private static Optional<OldInvestigator> oldInvestigatorOpt = null;

    private static Optional<OldInvestigator> newInvestigatorOpt = null;

    //enum identifying who was available
    private enum InvestigatorPresence
    {
        OLD,
        NEW,
        BOTH,
        NONE
    }

    public static void main(String[] args)
    {

        switch (getInvestigatorPresence(oldInvestigatorOpt, newInvestigatorOpt)) {
            case BOTH:
                // someService.updateInvestigator(oldInvestigatorOpt.get(), newInvestigatorOpt.get())
                break;
            case NEW:
                // someService.sendEmailToInvestigator(newInvestigatorOpt.get());
                break;
            case OLD:
                // someService.sendNotificationToLeader();
                break;
            case NONE:
                // handle
                break;
            default:
                break;
        }
    }

    private static InvestigatorPresence getInvestigatorPresence(Optional<OldInvestigator> oldInvestigatorOpt,
        Optional<OldInvestigator> newInvestigatorOpt)
    {
        boolean isOldPresent = oldInvestigatorOpt.isPresent() && oldInvestigatorOpt.get().getId().isPresent();
        boolean isNewPresent = newInvestigatorOpt.isPresent() && newInvestigatorOpt.get().getId().isPresent();

        if (isOldPresent) {
            if (isNewPresent) {
                return InvestigatorPresence.BOTH;
            } else {
                return InvestigatorPresence.OLD;
            }
        } else if (isNewPresent) {
            return InvestigatorPresence.NEW;
        } else {
            return InvestigatorPresence.NONE;
        }

    }
}
0 голосов
/ 05 июня 2019

Только для проверки на ноль вы могли бы рассмотреть следующий лучший способ.

Objects.isNull(Object obj)  

и

Objects.nonNull(Object obj) 

конечно несколько версий

Objects.requireNonNull()
...