Если есть метод
bool DoStuff() {
try {
// doing stuff...
return true;
}
catch (SomeSpecificException ex) {
return false;
}
}
это лучше назвать IsStuffDone()
?
Пользователь может неверно истолковать оба имени: если имя такое, DoStuff()
почему оно возвращает логическое значение? Если имя IsStuffDone()
такое, неясно, выполняет ли метод задачу или только проверяет ее результат.
Есть соглашение для этого случая? Или альтернативный подход, так как этот считается ошибочным? Например, в языках с выходными параметрами, таких как C #, логическая переменная состояния может быть передана методу как единое целое, а тип возвращаемого значения метода будет void
.
РЕДАКТИРОВАТЬ: В моей конкретной проблеме обработка исключений не может быть напрямую делегирована вызывающей стороне, потому что метод является частью реализации интерфейса. Следовательно, вызывающей стороне не может быть поручено иметь дело со всеми исключениями различных реализаций. Он не знаком с этими исключениями. Однако вызывающая сторона может иметь дело с пользовательским исключением, StuffHasNotBeenDoneForSomeReasonException
как было предложено в ответе и комментарии npinti .
источник
boolean
вместо переноса или передачи исключения почти всегда неверно.BadlyDesignedMethodInSeriousNeedOfRefactoring
? И чтобы ответить на ваш вопрос об исключениях - я бы либо позволил вызывающей стороне обработать их, либо перехватил бы их, а затем выдал пользовательское исключение, которое означает «этот метод не выполняет свою работу». Поделитесь и наслаждайтесь.if (FirstMethodSucceeds(problem) or SecondMethodSucceeds(problem) or ...) Hurray(); else UniversalSolve(problem);
. Делать то же самое с (пользовательскими?) Исключениями было бы бесполезно сложнее.Ответы:
В .NET у вас часто есть пары методов, один из которых может вызвать исключение (
DoStuff
), а другой возвращает логическое состояние и, при успешном выполнении, фактический результат с помощью параметра out (TryDoStuff
).(Microsoft называет это «шаблоном Try-Parse» , поскольку, возможно, наиболее ярким примером этого являются
TryParse
методы различных примитивных типов.)Если
Try
префикс редко встречается в вашем языке, то вам, вероятно, не следует его использовать.источник
if (TryDoStuff()) print("Did stuff"); else print("Could not do stuff");
на мой взгляд, довольно стандартная и интуитивно понятная идиома.TryDoStuff
методы, как предполагается, терпят неудачу чисто и не имеют побочного эффекта, когда они возвращают false.Remove
в .NET Framework также есть методы, например, которые удаляют элемент из структуры данных (напримерDictionary
) и возвращают abool
. Потребитель API может решить использовать его или игнорировать. Тем не менее, ошибки сообщаются как исключения.Что если вы просто сгенерировали исключение для вызывающего кода?
Таким образом, вы делегируете обработку исключений тому, кто когда-либо использует ваш код. Что делать, если в будущем вы хотели бы сделать следующее:
FileNotFoundException
выброшено, предпримите действие BЕсли вы отбросите свое исключение, указанное выше изменение просто повлечет за собой добавление дополнительного
catch
блока. Если вы оставите все как есть, вам нужно будет изменить метод и место вызова метода, который в зависимости от сложности проекта может находиться в нескольких местах.источник
DoStuff
сбоя, создание исключения для случая сбоя было бы сродни контролю потока программ с исключениями, что плохо. Исключения также имеют внутреннюю стоимость производительности. ЕслиDoStuff
сбой является редким случаем из-за ошибки, то исключения, безусловно, являются тем путем, который предлагает @npinti.DoStuff()
метод OP очищается после того, как внутренний код выдает исключение, а условия Post метода все еще верны, код возврата может быть лучшим вариантом, поскольку ошибка была обработана.DoStuff()
достаточно, и возвращаемое значение функции должно быть задокументировано, и вам не нужно упоминать его в имени функции, ища многие доступные API:PHP
C-Sharp
источник
В Java API-интерфейс Collection определяет метод add, который возвращает логическое значение. Это в основном возвращает, изменило ли дополнение коллекцию. Поэтому для a
List
он обычно возвращает значение true, поскольку элемент был добавлен, тогда как для aSet
он может возвращать значение false, если элемент уже был там, посколькуSet
s допускает каждый уникальный элемент не более одного раза.Тем не менее, если вы добавите элемент, который не разрешен в коллекции, например, нулевое значение, добавление будет выдавать
NullPointerException
вместо возврата false.Когда вы применяете ту же логику к вашему случаю, зачем вам возвращать логическое значение? Если это скрыть исключение, не надо. Просто брось исключение. Таким образом, вы можете увидеть, что пошло не так. Если вам нужен логический тип, потому что он не мог быть выполнен, по какой-то другой причине, кроме исключения, назовите метод
DoStuff()
, поскольку он представляет поведение. Это делает вещи.источник
Может произойти сбой по разным причинам, исключение, нормальные условия, поэтому будет использовать это:
Важно документировать, что означает логическое значение.
источник
У меня обычно есть методы, возвращающие
OperationResult
(илиOperationResult<T>
) и устанавливающиеIsSuccess
свойствоOperationResult
соответствующим образом. Если «обычный» метод void, вернитесьOperationResult
, если «обычный» метод возвращает объект, вернитесьOperationResult<T>
и установитеItem
свойствоOperationResult
соответствующим образом. Я также предложил бы иметь методы,OperationResult
такие как.Failed(string reason)
и.Succeeded(T item)
.OperationResult
быстро становится привычным типом в ваших системах, и разработчики узнают, как с этим справиться.источник
Это действительно зависит от языка, который вы используете. Как и для некоторых языков, существуют соглашения и протоколы, которые на самом деле не существуют во многих языках или вообще отсутствуют.
Например, в языке Objective-C и именах методов iOS / Mac OS X SDK обычно используются следующие строки:
Как видите, есть метод с именем viewDidLoad. Я предпочитаю использовать этот тип именования, когда создаю свои собственные приложения. Это можно использовать, чтобы проверить, должно ли что-то происходить, как вы сказали. Я считаю, что вы слишком глубоко думаете о том, что вы называете ваши методы. Большинство методов возвращают статус того, что они делают независимо, например:
В PHP mysql_connect () вернет false в случае сбоя соединения. Это не говорит, что это будет, но это делает, и документация говорит, что это делает так, что это не может быть неправильно истолковано программисту.
источник
Я хотел бы предложить использовать префикс «Try». Это хорошо известный шаблон для ситуаций, когда метод может быть успешным или нет. Этот шаблон именования использовался Microsoft в .NET Framework (например, TryParseInt).
Но, возможно, дело не в именах. Это о том, как вы проектируете параметры ввода / вывода вашего метода.
Моя идея состоит в том, что если у метода есть возвращаемое значение, то целью вызова этого метода должно быть получение этого возвращаемого значения. Таким образом, вы должны избегать использования типа возврата для указания статуса операции.
В C # я предпочитаю использовать параметр out. Используя out я отмечаю параметр как побочный параметр. Специально, что C # 6 будет поддерживать объявление встроенных переменных.
источник
Я бы выбрал имя в зависимости от основной роли метода. Тот факт, что метод возвращает логическое значение, не обязывает префикс «Is». Давайте немного Java-кода, который довольно широко использует префикс «Is». Возьмите взгляд на
java.io.File.delete()
. Это возвращаетсяboolean
, но это не называетсяisFileDeleted()
. Причина в том, что основная роль метода заключается в удалении файла. Кто-то вызывает этот метод с намерением удалить файл.Логическое значение существует только для того, чтобы сообщить результат работы. С другой стороны посмотрим
java.util.Map.isEmpty()
. Очевидно, вы вызываете такой метод, чтобы узнать, пуста ли коллекция. Вы не хотите ничего делать. Вы просто хотите узнать, каково текущее состояние.Так что лично я бы точно придерживался
DoStuff()
.Это несколько очень важный вопрос для меня. Много раз, когда я поддерживаю унаследованный код, я сталкиваюсь с тем, что лично называю «ложным методом». Имя предлагает действие A, но тело выполняет действие B. Самый странный пример - метод получения, изменяющий данные в базе данных.
источник