Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 14.11.08 18:12
Оценка:
Интерсно мнение, может ли идеологически сеттер кидать исключение?

Мое ИМХО сеттер не должен кидать никаких исключений. Валидация данных должна проиходить на момент дейтсвия.

Пример.

class Person
{
Age
{
get;
set;
}

void Drink()
{
if (Age < 18)
{
throw new InvalidOperation();
}
}

void Born()
{
if (Age > 0)
{
throw new InvalidOperation();
}
}

void BecomeEmbryo()
{
if (Age < 0)
{
throw new InvalidOperation();
}
}
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re: Exceptions в сеттерах
От: C...R...a...S...H  
Дата: 14.11.08 18:24
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Интерсно мнение, может ли идеологически сеттер кидать исключение?


MC>Мое ИМХО сеттер не должен кидать никаких исключений. Валидация данных должна проиходить на момент дейтсвия.


А по чему Setter не может кидать исключения??
Вы представте вы что у вас просто метод

void SetName(string name)


При этом не надо забывать что у инстансов есть свое собственное состояние, на основании которого они могут принимать те или иные решения.
И вообще как же тогда жить с Lazy Load?
Там было написано русским по белому...
Re[2]: Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 14.11.08 18:43
Оценка:
Здравствуйте, C...R...a...S...H, Вы писали:

CRA>А по чему Setter не может кидать исключения??

CRA>Вы представте вы что у вас просто метод

CRA>
CRA>void SetName(string name)
CRA>


CRA>При этом не надо забывать что у инстансов есть свое собственное состояние, на основании которого они могут принимать те или иные решения.

CRA>И вообще как же тогда жить с Lazy Load?

Подчеркну я специально говорю про идеолгию. Как бы вы предпочли реализовать сеттер для Age в моем примере. Проверив его на больше чем 0 и кинув ексепшен? Или дали бы туда попасть -10, а потом уже на момент действия проверили что человек не может пить если ему меньше чем 0 лет?

По ходу я обычно не представляю методы . Я делаю методы. Так если у меня состояние обьекта может сломаться если я не проконтролирую что туда присваеваеться, то я делаю специальный метод SetName. И там уже кидаю ексепшен. Но это все мое ИМХО. Мне интерсно ваше .
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[3]: Exceptions в сеттерах
От: C...R...a...S...H  
Дата: 14.11.08 19:08
Оценка: +3
Здравствуйте, Mike Chaliy, Вы писали:


MC>Подчеркну я специально говорю про идеолгию. Как бы вы предпочли реализовать сеттер для Age в моем примере. Проверив его на больше чем 0 и кинув ексепшен? Или дали бы туда попасть -10, а потом уже на момент действия проверили что человек не может пить если ему меньше чем 0 лет?


MC>По ходу я обычно не представляю методы . Я делаю методы. Так если у меня состояние обьекта может сломаться если я не проконтролирую что туда присваеваеться, то я делаю специальный метод SetName. И там уже кидаю ексепшен. Но это все мое ИМХО. Мне интерсно ваше .


Мое мнение такое, что exception в setter'ах это нормально.
Другой вопрос как далеко можно зайти в проверках, но стандартные проверки может ли данное значение быть установлено, думаю стоит размещать в сеттерах.
Я повторюсь: не всегда внутреннее состояние объекта может быть доступно из вне.
Как пример: pattern State
Когда вам приходит объект в каком то состоянии и вы пытаетесь его использовать не правильным образом
Там было написано русским по белому...
Re[4]: Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 14.11.08 19:32
Оценка:
Здравствуйте, C...R...a...S...H, Вы писали:

CRA>Мое мнение такое, что exception в setter'ах это нормально.


ОК, пасиба за ответы, можно я еще по задаю вопросов?

А вы пишите ожидаемые исключения когда пишите дведокс для свойств?

Пример.

/// <summary>
/// Get or set age.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">Throws when age is less then zero.</exception>        
/// <returns></returns>


Вы как пользователь АПИ в каких случаях ожидаете что Person для свойства Age крешанеться? Как обычно выглядит код который вы пишете?


try
{
    Person p = new Person();
    p.Age = -1;
    p.Age = 10;
    p.Drink();
}
catch(ArgumentException e)
{
    // Bit strange...
}


или

try
{
    Person p = new Person { Age = 0 };
}
catch(ArgumentException e)
{
    // Bit strange...
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[5]: Exceptions в сеттерах
От: C...R...a...S...H  
Дата: 14.11.08 19:57
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

Так же как для таких методов
System.Threading.Thread.IsBackground

Exceptions:
System.Threading.ThreadStateException: The thread is dead.


System.Configuration.ConfigurationElement

Exceptions:
System.Configuration.ConfigurationErrorsException: The element has already been locked at a higher configuration level.



System.Net.HttpWebRequest.AutomaticDecompression


Exceptions:
System.InvalidOperationException: The object's current state does not allow this property to be set.


Последний пример я думаю очень показательный.
Там было написано русским по белому...
Re[6]: Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 14.11.08 20:20
Оценка:
Здравствуйте, C...R...a...S...H, Вы писали:

CRA>Последний пример я думаю очень показательный.


Жаль что вы не ответили на вопросы.... Если вам охота примеров от Майкрософт, то зайдите в любой контрол. Весь дизайнер на этом построен.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[7]: Exceptions в сеттерах
От: C...R...a...S...H  
Дата: 14.11.08 20:33
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, C...R...a...S...H, Вы писали:


CRA>>Последний пример я думаю очень показательный.


MC>Жаль что вы не ответили на вопросы.... Если вам охота примеров от Майкрософт, то зайдите в любой контрол. Весь дизайнер на этом построен.

Думаю ответ был дан:

The object's current state does not allow this property to be set.


То есть при не правильном использовании объекта, он может матюкаться экшепшанапи даже при установке свойств.
Там было написано русским по белому...
Re: Exceptions в сеттерах
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 14.11.08 20:56
Оценка: 11 (2) +3 :))) :)
Здравствуйте, Mike Chaliy, Вы писали:

R>[skipped]

Вы, прошу прощения, с какой планеты? Во-первых, на планете Земля человек может спокойно напиться в 13 лет, буквально неделю назад у друга с дочерью такая беда приключилась. Во-вторых, с чего вы взяли, что у человека обязательно должен быть метод Drink? Серьезно, есть трезвенники. В-третьих, кто встроил в человека механизм проверки возраста? Пил в подворотне в 15 лет и, знаете, внутри никакие шестеренки не начинали скрипеть. В-четвертых, согласно КоАП крепкие алкогольные официально позволительны только с 21 года, 18 — это ваш ценз, вы с 18 начали?

Это лирика, но очень показательная. Во-первых, проверка, которую вы засунули в метод Drink — не является ответственностью Person. Во-вторых, если ваш Person — это некоторый вид людей, которые пить начинают строго на следующий день после 18-летия, а также могут иметь отрицательный возраст, то все OK, но в отношении людей планеты Земля корректнее устанавливать значение age в конструкторе, а при несоблюдении переданным в конструктор значением age контракта ОДЗ (математику помните?) возраста человека — кидать исключение. Было бы неплохо сразу при попытке создать человека с возрастом -5 лет (ага, родится через 5 лет только?), получить исключение, причем осмысленное "это не человек!", а не в момент попытки напоить это нечто с очень неосмысленным исключением "ему нет 18!" (ему не просто нет 18, оно не человек). В-третьих, кошернее использовать стандартные исключения, если логически таковые существуют в SDK, в конструкторе, к примеру, ArgumentException.

Исключения должны кидать конструкторы тем самым отменяя создание, полностью исключая появления в памяти объекта с недопустимыми характеристиками. Аналогично, для mutable-объектов подобные же проверки должны быть в setter. Могу напугать: есть движки защитного программирования, которые могут кинуть исключение из getter-а.
Re[2]: Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 14.11.08 21:49
Оценка:
Здравствуйте, rsn81, Вы писали:

R>>[skipped]


Улыбнуло . Особенно про планету... Пасиба за ответы.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[8]: Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 14.11.08 21:49
Оценка:
Здравствуйте, C...R...a...S...H, Вы писали:

CRA>Думаю ответ был дан:


CRA>

CRA>The object's current state does not allow this property to be set.


CRA>То есть при не правильном использовании объекта, он может матюкаться экшепшанапи даже при установке свойств.


Тоесть если я вам приведу пример где проверка и исключение делаеться на вызов, то вы тоже безаговорочно примите? Ну или давайте по другому. Вы уверены что все что сделано в фремворке идеологически правильно? Вы уверены что это небыло исключением из идеологии?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[9]: Exceptions в сеттерах
От: C...R...a...S...H  
Дата: 15.11.08 10:08
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:


MC>Тоесть если я вам приведу пример где проверка и исключение делаеться на вызов, то вы тоже безаговорочно примите? Ну или давайте по другому. Вы уверены что все что сделано в фремворке идеологически правильно? Вы уверены что это небыло исключением из идеологии?


Вот вы задумайтесь.
У вас есть объект состояниме которого вы не управляете.
Тоже самое соединение с другим серверм.
Вы его открывает и с ним работаете.
Через некоторое время соединение отрубается, но вы об этом пока не знаете, а просто пытаетесь установить размер пакета для пересылки данных.
Как должен вести себя объект в таком случае?
Там было написано русским по белому...
Re: Exceptions в сеттерах
От: kisel Украина  
Дата: 15.11.08 10:57
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Интерсно мнение, может ли идеологически сеттер кидать исключение?


MC>Мое ИМХО сеттер не должен кидать никаких исключений. Валидация данных должна проиходить на момент дейтсвия.


Нужно!!!
1)Объект должен поддерживать только корректное состояние, а не быть своего рода свалкой.

2)При твоём подходе — get должен относиться к моменту действия.
Если такового не будет, то вообще лажа, тобишь, появляется вероятность того, что что сущности которые связаны с твоим Person могут оперировать не допустимыми данными.

3)На момент опрашивания состояния объекта(дёрнуть get) — не желательно кидать исключение и производить какие то действия.
По крайней мере разработчик, который будет использовать твой Person мягко говоря удивиться — такому поведению

4)Как дебажить это дело собираешься? Задал возраст равным -1 и пошёл процесс, после этого ты опросил Person и получил исключение
и хочется же узнать, откуда взялся -1 а в StackTrace уже и в помине нет места, в котором задавался возраст равным -1.

5)Если провалидируешь возраст на сеттере то ты это сделаешь в одном месте!!!!!!!
А если на момент совершения действия, то успевай только отслеживать в каких местах используется возраст и расставлять перед вызовами метод аля ValidateAge(). А это уже COPY+PASTE.

6) Модульное тестирование при этом усложняется.

А какие же плюсы во всём этом, дай подумать ...Хм ... Что то не видать!

Итого ... выкинь эту идею из головы
Re[2]: Exceptions в сеттерах
От: kisel Украина  
Дата: 15.11.08 11:03
Оценка:
>>Здравствуйте, Mike Chaliy, Вы писали:

5 аргумент не считается, забыл что у нас же предполагается валидировать на get-е
Re[2]: Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 15.11.08 11:24
Оценка:
Здравствуйте, kisel, Вы писали:

K>1)Объект должен поддерживать только корректное состояние, а не быть своего рода свалкой.


Если я хочу потдерживать корректное состояние то у меня по умолчанию все свойства будут ридонли. У меня будут методы которые будут это состояние менять. Так например у меня есть аппонтмент.

class Appointemet
{
DateTime startTime;
DateTime endTime;
int Duration; // у меня по бизнесу это дени.
}

Если мне надо аппоинтменту укзать его даты то будет метод SetDates(DateTime start, DateTime end) этот же метод завалидирует что end > start, посчитает дюрейшен.

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

Єто реально мое ИМХО что юзабилити АПИ значительно выше, если сеттеры не кидают исключения. Точно так же как мое ИМХО что сеттеры не должны изменять соседние поля....

K>4)Как дебажить это дело собираешься? Задал возраст равным -1 и пошёл процесс, после этого ты опросил Person и получил исключение

Обьясню. Возраст -1 это вполне нормальное значение. Тоесть существуют таки задачи в которых это необходимо. Точно также как и со складами. Какбудтобы физически не может быть на складе -20 мочалок. Ан нет, может, это более чем повседневная задача в складском учете.

Дальше больше предположим что -1 это не валидное состояние по бизнесу.
Тогда есть два варианта.

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

б) Не потдерживает. Тоесть просто крешиться на момент установки.

В любом случае момент установки это действие.

K>5)Если провалидируешь возраст на сеттере то ты это сделаешь в одном месте!!!!!!!

Основная мысля это то что для каждого БЛ метода это может быть свое. Тоесть для Дринк должно быть 18 (21, хз у меня не было случая проверить...), а для метода Слип вообще не существенно какой возраст....

K>Итого ... выкинь эту идею из головы


Я же не советов просил. Тем более меня слегка удивляет пренебрежительное повествование вас и rsn81, но мы люди не гордые... Инфа полезней, так что проглотим.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[3]: Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 15.11.08 11:44
Оценка:
Здравствуйте, kisel, Вы писали:

>>>Здравствуйте, Mike Chaliy, Вы писали:


K>5 аргумент не считается, забыл что у нас же предполагается валидировать на get-е


Не-не, я нигде не прдлагал валидировать в геттере. Геттеры по гаидлайнам не должны кидать ексепшены, как и констуркторы собсно. Так что ваше замечание вполне валидно и я на него даже ответил .
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[3]: Exceptions в сеттерах
От: kisel Украина  
Дата: 15.11.08 13:33
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:
MC>Я же не советов просил. Тем более меня слегка удивляет пренебрежительное повествование вас и rsn81, но мы люди не гордые... Инфа полезней, так что проглотим.
Так мы любя ... Хорошо, что не гордый ...

По поводу того, что должно быть свойство Age и метод SetAge — как то сложновато закрутил.Код должен быть — friendly.
Если бы мне пришлось юзать этот классец, то первая мысль пришла бы в голову, зачему 2 метода нужны (свойство — это всего лишь 2 сгруппированных метода, может быть и один).
У меня бы мозг закипел и подумал про себя — "снова какой-то индусский код подсунули "
Re[4]: Exceptions в сеттерах
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 15.11.08 14:28
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Не-не, я нигде не прдлагал валидировать в геттере. Геттеры по гаидлайнам не должны кидать ексепшены, как и констуркторы собсно. Так что ваше замечание вполне валидно и я на него даже ответил .

Выделенное — что за гайдлайны такие?
Re[4]: Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 15.11.08 14:40
Оценка:
Здравствуйте, kisel, Вы писали:

K>У меня бы мозг закипел и подумал про себя — "снова какой-то индусский код подсунули "


А у меня четкие ассоциации с индусами, когда вижу код свойств с логикой...
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[5]: Exceptions в сеттерах
От: Mike Chaliy Украина http://chaliy.name
Дата: 15.11.08 14:46
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Не-не, я нигде не прдлагал валидировать в геттере. Геттеры по гаидлайнам не должны кидать ексепшены, как и констуркторы собсно. Так что ваше замечание вполне валидно и я на него даже ответил .

R>Выделенное — что за гайдлайны такие?

.Net Framework Design Guidelines
тут есть видио http://channel9.msdn.com/pdc2008/PC58/, помойму на 20 минуте про геттеры, чуть дальше про контсрукторы.

Хотя я там слишком жестко написал, в гаидлайнах речь идет про "хотелось бы что бы не кидали". "не должны" лучше читать как "не хотлоесь бы". Но так как весь суть разговора идет про идеолгическую часть, которая по необходисомти может быть попрана. То ИМХО вполне допустимо использовать черное и белое.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.