Должны ли все методы, которые что-то делают, но не возвращают данные, возвращать код успеха? - PullRequest
2 голосов
/ 11 января 2012

Простой вопрос о передовых практиках, который я не видел в рассматриваемых мной вводных книгах по программированию ...

Если функция или метод выполняет действие, но не возвращает реальные данные, например, функция, которая увеличивает свойство класса или значение базы данных, должно ли оно всегда возвращать логическое значение успеха?

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

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

Но я просто любитель. Что делают профессионалы?

Ответы [ 4 ]

1 голос
/ 11 января 2012

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

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

0 голосов
/ 11 января 2012

Мнения будут варьироваться по этому вопросу, как и по многим вопросам «передового опыта».

Но есть общепринятый принцип, называемый Разделение команд и запросов , который говорит, что метод долженсделать что-то или , вернуть значение, а не оба.

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

0 голосов
/ 11 января 2012

Честно говоря, есть верный способ сделать что-то, и мне нужно, чтобы это было сделано. Много раз я оказываюсь в обеих ситуациях.

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

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

Только мои 20 с лишним лет работы в трудных ситуациях и звонков от клиентов, которым нужно приложение, созданное или исправленное за неделю или меньше.

0 голосов
/ 11 января 2012

Возвращать значения успеха, когда вы не ожидаете, что что-то не получится, обычно плохой дизайн. Вы можете забыть проверить возвращаемые значения или проверить их неправильно, и если вы начнете использовать разные значения для разных ошибок, вещи быстро выйдут из-под контроля. (-1: успех или неудача? Это зависит от автора!)

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

Вы не указали язык, поэтому вот пример VB.NET, который делит число:

Function FloorDivide(ByVal a As Integer, ByVal b As Integer) As Integer
    Dim result As Boolean = a / b

    If Double.IsNaN(result) Then Throw New DivideByZeroException()

    Return CInt(Math.Floor(result))
End Function

Вы можете использовать его без проверки значения успеха, но вы все равно можете обрабатывать ошибки, используя операторы Try...Catch:

Try
    FloorDivide(1, 0)
Catch ex As DivideByZeroException
    MessageBox.Show("Something went terribly wrong! :D")
    'Exit, maybe?
End Try

(Не то чтобы я говорил, что вы должны защищаться от деления на ноль таким образом; отфильтруйте свои данные!)

Если вы забудете выполнить эту проверку, вам вскоре напомнят на этапе тестирования, вместо того, чтобы ваш код молча провалился. Это также намного чище, и область действия Try...Catch может быть настолько большой, насколько вы хотите, возможно, обрабатывая любые ошибки, возникающие в конкретном подверженном ошибкам методе, и выбрасывая их. Кто знает?

Так что, как правило, используйте исключения. Однако, если вы планируете справиться с ними, вам необходимо выполнить проверку.

...