Возвращает как результат вычисления, так и статус.Лучшие практики - PullRequest
3 голосов
/ 13 декабря 2011

Я думал о шаблонах, которые позволяют мне возвращать как результат вычисления, так и статус:

Есть несколько подходов, о которых я мог бы подумать:

  • функция возвращает результат вычисления, состояние возвращается через параметр out (не все языки поддерживают параметры out, и это кажется неправильным, поскольку в общем случае вы не ожидаете изменения параметров).

  • функция возвращает объект / пару, состоящую из обоих значений (недостатком является то, что вам нужно создать искусственный класс просто для того, чтобы вернуть результат функции или использовать пару, которая не имеет смыслового значения - вы знаете, какой аргумент является каким по его порядку). 1011 *

  • если ваш статус - просто успех / сбой, вы можете вернуть значение вычисления, а в случае ошибки вывести исключение (выглядит как лучший подход, но работает только со сценарием успеха / сбоя и не должно использоваться для управление нормальным программным потоком).

  • функция возвращает значение, аргументы функции являются делегатами процедур onSuccess / onFailure.

  • есть класс метода (с полным состоянием), который имеет поле состояния и метод, возвращающий результаты вычислений (я предпочитаю иметь объекты без состояния / неизменяемые).

Пожалуйста, дайте мне несколько советов о плюсах, минусах и предусловиях ситуаций использования вышеупомянутых подходов или покажите мне другие схемы, которые я мог бы использовать (предпочтительно с подсказками о предпосылках, когда их использовать).


EDIT: Пример из реальной жизни: Я занимаюсь разработкой java ee интернет-приложения, и у меня есть класс, разрешающий параметры запроса, преобразующий их из строки в некоторые объекты бизнес-логики. Resolver проверяет в БД, создается ли объект или редактируется, а затем возвращает контроллеру либо новый объект, либо объект, полученный из БД. Контроллер выполняет действия на основе статуса объекта (новый / редактируемый), считанного из распознавателя. Я знаю, что это плохо, и я хотел бы улучшить дизайн кода здесь.

Ответы [ 2 ]

1 голос
/ 02 февраля 2013

Я склонен либо использовать параметры out, либо использовать структуру «открытого поля», которая просто содержит открытые поля и указывает, что его целью является просто передача значений этих полей.В то время как некоторые люди предполагают, что все должно быть «инкапсулировано», я хотел бы предложить, чтобы, если вычисление естественным образом выдает два double значения, называемые коэффициентами Мо и Ларри, указывая, что функция должна возвращать «простую структуру старых данных с полямиТипы double, называемые MoeCoefficient и LarryCoefficient ", служат для полного определения поведения структуры.Хотя структура должна быть объявлена ​​как тип данных вне метода, выполняющего вычисления, ее содержимое, представленное в виде открытых полей, будет ясно, что ни одна из семантик, связанных с этими значениями, не содержится в структуре - они всесодержится в методе, который его возвращает.

Некоторые люди утверждают, что структура должна быть неизменной или что она должна включать логику проверки в своем конструкторе и т. д. Я бы предложил обратное.Если цель структуры состоит в том, чтобы позволить методу возвращать группу значений, этот метод должен нести ответственность за обеспечение того, чтобы он помещал правильные значения в структуру.Кроме того, хотя в структуре нет ничего плохого в том, что конструктор представляет «удобный элемент», просто наличие кода, который будет возвращать заполнение структуры в полях по отдельности, может быть быстрее и понятнее, чем вызов конструктора, особенно если значение будет сохранено.в одном поле зависит от значения, хранящегося в другом.

Если структура просто предоставляет свои поля публично, то семантика очень ясна: MoeCoefficient содержит последнее значение, которое было записано в MoeCoefficient, иLarryCoefficient содержит последнее значение, записанное в LarryCoefficient.Значение этих значений будет полностью зависеть от того, какой код их пишет.Скрытие полей за свойствами затемняет эти отношения и может также снизить производительность.

1 голос
/ 31 декабря 2011

функция возвращает результат вычисления, статус возвращается через out параметр (не все языки поддерживают параметры, и это кажется неверно, так как в общем случае вы не ожидаете изменения параметров).

Если язык поддерживает несколько выходных значений, то язык явно создан для их поддержки. Было бы стыдно не использовать их (если только в этом конкретном сообществе нет сильных мнений против них - это может быть в случае языков, которые пытаются и делают все)

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

Я не знаю об этом недостатке. Мне кажется, что запись или класс с именем «MyMethodResult» должны иметь достаточно семантики. Вы также всегда можете использовать такой класс в исключении: , если , конечно, вы находитесь в исключительном состоянии. По моему мнению, создание какого-либо массива / объединения / пары было бы менее приемлемым: вы неизбежно потеряли бы где-нибудь информацию.

если ваш статус просто успех / неудача, вы можете вернуть вычисление значение, а в случае ошибки выведите исключение (выглядят как лучшие подход, но работает только со сценарием успеха / неудачи и не должен злоупотреблять для контроля нормального выполнения программы).

Нет! Это худший подход. Исключения должны использоваться именно для этого, исключительные обстоятельства. Если нет, то они остановят отладчики, поставят коллег по пятам, нанесут ущерб производительности, заполнят вашу систему регистрации и запустят ваши юнит-тесты. Если вы создаете метод для проверки чего-либо, тогда тест должен возвращать состояние, а не исключение: для реализации возвращение отрицательного значения не исключительное.

Конечно, если во время синтаксического анализа у вас заканчиваются байты из файла, обязательно выведите исключение, но не выбрасывайте его, если ввод неправильный и ваш метод называется checkFile.

функция возвращает значение, аргументы функции являются делегатами Процедуры onSuccess / onFailure.

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

существует класс метода (с полным состоянием), который имеет поле состояния, и метод, возвращающий результаты вычислений (я предпочитаю иметь объекты без состояния / неизменяемые).

Да, я предпочитаю это. Есть производители результатов и сами результаты. Нет необходимости объединять их и создавать объект с состоянием.

В конце концов, вы хотите перейти к02.produceFrom (x): Результат, на мой взгляд. Это вариант 1 или 2а, если я считаю правильно. И да, для 2а это означает написание дополнительного кода.

...