Существует ли шаблон проектирования Pass / Fail? - PullRequest
0 голосов
/ 27 апреля 2018

Не совсем уверен, что формальный термин для такой модели / проблемы, но вот с чем я сталкиваюсь:

У меня есть операция, которая несколько велика. Это может или пройти или потерпеть неудачу. Каждый проход или сбой несет с собой либо результат успешной операции, либо информацию о том, почему операция не удалась. Я изо всех сил пытаюсь построить эту функцию "правильно".

class Pass{
    int someGoodStuff;
    double someOtherGoodStuff;
}

class Fail{
    String failureMsg;
    float howMuchOperationWasOffBy;
}

class Operator{
    public ??? operation(){
    }
}

Подход 1 : Состояния отказа похожи на исключения. Давайте бросим их. Это позволяет мне включить информацию об ошибке и сделать тип возврата просто Pass. Однако эти состояния отказа не являются ошибками языка программирования, они являются ошибками бизнес-логики. Таким образом, в этом подходе меня не устраивают две вещи: во-первых, он путает сбой бизнес-логики с фактическими ошибками Java (что кажется неправильным), и во-вторых, он поддерживает нормальный поток выполнения без каких-либо веских причин для этого.

Подход 2 : Функции в java любят возвращать один тип объекта, поэтому Pass и Fail реализуют интерфейсный Result и имеют возвращаемый тип функции.

interface Result{...}
class Pass implements Result{...}
class Fail implements Result{...}
class Operator{
    public Result operation(){...}
}

Однако, pass и fail указывают, что функция полностью отличается. У них мало или нет перекрывающихся переменных или функций. Это кажется неправильным и сводит меня к необходимости instanceof всей важной информации из пропусков и неудач.

Подход 3 : Какой-то объект объединения, который может быть как пройденным, так и неудачным (но не оба)

class Result{
    public Pass pass=null;
    public Fail fail=null;
}

class Operator{
    public Result operation(){...}
}

Это имеет то преимущество, что я могу сказать что-то вроде

Result result=op.operation();
if (result.succeed()){
    doStuffWithPass(result.getPass());
}else{
    doStuffWithFail(result.getFail());
}

Что в основном я и делал с instanceof, но выглядела лучше; Теперь код выглядит так, как вы этого ожидаете. Понятно следовать.

Однако в Java нет настоящих типов Union. Я должен убедиться, что кто-то случайно не попытается связываться с переменными прохода Результата сбоя или наоборот. Кроме того, каждый метод, который я вызываю для типа объединения, должен быть основан на выяснении, является ли это проходом или неудачей (ветвь That If внезапно должна быть везде)

Наконец, хотя это и не является реальной проблемой, я полагаю, что такая схема распределяет пространство как для прохода, так и для неудачи для каждого результата, когда я знаю, что он может быть только одним из них (т.е. он должен занимать пространство равно Max(space(Pass),space(Fail)))

Ни один из этих подходов не кажется идеальным. Я чувствую, что должен быть образец, чтобы решить такую ​​проблему. Есть ли?

1 Ответ

0 голосов
/ 27 апреля 2018

В этом случае выдается ошибка. Подход кажется наилучшим.

Причины

  1. Вы можете создать несколько пользовательских исключений для нескольких типов, и когда что-то не так, происходит. При таком подходе вы гарантируете, что всякий раз, когда происходит что-то плохое, ваша программа возвращает элемент управления с указанной ошибкой.

  2. В качестве типа возврата вы можете вернуть свой Результат с определенным значением. Поэтому, когда ваша программа возвращает что-то, она кажется работающей или проходящей

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