2010-06-08 4 views
8

Я искал какой-то код, который унаследовал, и я не мог решить, нравится ли мне немного кода.Должен ли метод connect возвращать значение?

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

bool Connect(connection parameters){...} 

Она возвращает истину, если он подключается успешно, иначе ложь.

Я написал такой код в прошлом, но теперь, когда я вижу этот метод, мне не нравится это по ряду причин.

  1. Его легко написать код, который просто игнорирует возвращаемое значение или не реализует его, возвращает значение.

  2. Невозможно вернуть сообщение об ошибке.

  3. Проверка возврата метода не очень хорошо выглядеть:

    если {....}

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

void Connect(Connection Parameters, out bool successful, out string errorMessage){...} 

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

У кого-нибудь есть мысли по этому поводу?

Благодаря Матф

ответ

3

У меня есть только мнение, поэтому возьмите его за то, что его стоит.

Метод, названный так «Подключение», это заказ. Это похоже на то, чтобы дать солдату «Jump» или «Shoot». Вы не ожидаете, что солдат сообщит об этом, если он не сможет выполнить заказ, и это было бы редко случается.

Как таковой, у меня есть тенденция не иметь возвращаемого значения для таких методов, но если есть вероятность, что при регулярном использовании метода будут сбои, тогда я создам второй метод с именем TryXYZ, возвращая bool, и, при необходимости, предоставит мне результаты любого XYZ как параметры.

Это следует стандарту, изложенному в методах анализа различных числовых типов в .NET BCL.

Так что в вашем случае, я бы, наверное:

void Connect(connection parameters); 
bool TryConnect(connection parameters, out status); 

Хорошая вещь, что если вы строите метод TryConnect правильно, соединение становится очень легко.

Пример:

public bool TryConnect(string connectionString, out ConnectionStatus status) 
{ 
    ... try to connect 
    ... set status, and return true/false 
} 

public void Connect(string connectionString) 
{ 
    ConnectionStatus status; 
    if (!TryConnect(connectionString, out status)) 
     switch (status) 
     { 
      case ConnectionStatus.HostNotFound: 
       throw new HostNameNotFoundException(); 
      ... 
     } 
} 

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

+0

Мне нравится этот подход. Это, безусловно, делает вещи ясными. Я думаю, что объединение метода TryConnect (...) с предложением Foovanadil о пользовательском типе возврата - это то, с чем я собираюсь идти. –

+0

Если ваше соединение недолговечно, вы также можете рассмотреть возможность возврата IDisposable для простой очистки соединения следующим образом: using (var connection = connect (...)) { // используйте соединение } –

12

Я выбрал бы за исключением по сравнению с out параметрами. Если вы хотите, чтобы потребители вашего класса заботились о них, заботитесь об их исключении или оставляйте их в покое. Используя параметры out, вы просто делаете свою жизнь более неудобной, если они не имеют, чтобы ухаживать за ними, используя для этого переменные throwaway. Также учтите, что если ваша функция уже находится в дикой природе, вы вносите изменения, если вы меняете подпись (вместо дополнительной перегрузки).

Программисты ожидают исключения в случаях ошибок, особенно на таких языках, как C#. Мы прошли обучение.

+1

Я согласен с этим ответом. Обычно неспособность подключиться к чему-то считается исключительным случаем и, как правило, рассматривается как таковая во всей .NET Framework (ADO.NET, WCF). Возвращение пары «Успешное/ошибочное сообщение» - это старое программирование стиля Windows в школьной школе - гораздо лучше обрабатывать строго типизированное исключение с помощью try/catch (и это соглашение). Если у вас есть инструменты в вашем распоряжении, вы должны их использовать. – luksan

1

Я вижу ваши баллы, кроме как добавить 2c.

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

Я бы хотел вернуть пользовательский тип из метода connect, который хранит всю релевантную информацию, а не несколько параметров вывода. Подумайте о будущей расширяемости, что, если вам нужно включить дополнительную информацию в будущем.Добавление дополнительных выходных параметров является изменением разрыва.

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

Я согласен с тем, что проверка возвращаемого значения исходного метода не является идеальной.

0

Не уверен, что это лучше, чем ваш код рефакторинга, но, надеюсь, это может дать вам другую идею.

Для моих проектов я создаю метод, который возвращает последнее сообщение об ошибке.

string Error = ''; 
bool Connect(connection parameters) 
{ 
// do my connection here 
// if there's an error set string variable Error 
// This way you can set different error message depending on what you're doing 
} 

string lastErrorMessage(){ 
// return Error string 
} 

Таким образом, вы можете сделать это:

if(!connect(...)) 
{ 
string message = lastErrorMessage(); 
// Then do what you need here. 
} 

Это может быть не лучшим образом, но должно помочь вам :)

1

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

Что касается ожиданий, пусть исключение будет зависеть от вызывающего кода, что заставит вызывающего абонента заботиться. :)

1

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

  1. Использование регистрации. Недостатком является то, что сообщения записываются в журнал, но нет (без особых усилий), доступных для вызывающего.
  2. Используйте boolean return и предоставьте методы для запроса последней ошибки (например, errno в C). ИМХО тоже не приятно.
  3. Восстановите свой код, верните объект класса соединения. Предоставьте методы для запроса состояния соединения.
  4. возвращает экземпляр класса, который собирает всю необходимую информацию, он же isSuccessfull(), getErrorString и т.д.
Смежные вопросы