Здравствуйте, Mike Chaliy, Вы писали:
MC>Интерсно мнение, может ли идеологически сеттер кидать исключение?
MC>Мое ИМХО сеттер не должен кидать никаких исключений. Валидация данных должна проиходить на момент дейтсвия.
А по чему Setter не может кидать исключения??
Вы представте вы что у вас просто метод
void SetName(string name)
При этом не надо забывать что у инстансов есть свое собственное состояние, на основании которого они могут принимать те или иные решения.
И вообще как же тогда жить с Lazy Load?
Здравствуйте, C...R...a...S...H, Вы писали:
CRA>А по чему Setter не может кидать исключения?? CRA>Вы представте вы что у вас просто метод
CRA>
CRA>void SetName(string name)
CRA>
CRA>При этом не надо забывать что у инстансов есть свое собственное состояние, на основании которого они могут принимать те или иные решения. CRA>И вообще как же тогда жить с Lazy Load?
Подчеркну я специально говорю про идеолгию. Как бы вы предпочли реализовать сеттер для Age в моем примере. Проверив его на больше чем 0 и кинув ексепшен? Или дали бы туда попасть -10, а потом уже на момент действия проверили что человек не может пить если ему меньше чем 0 лет?
По ходу я обычно не представляю методы . Я делаю методы. Так если у меня состояние обьекта может сломаться если я не проконтролирую что туда присваеваеться, то я делаю специальный метод SetName. И там уже кидаю ексепшен. Но это все мое ИМХО. Мне интерсно ваше .
MC>Подчеркну я специально говорю про идеолгию. Как бы вы предпочли реализовать сеттер для Age в моем примере. Проверив его на больше чем 0 и кинув ексепшен? Или дали бы туда попасть -10, а потом уже на момент действия проверили что человек не может пить если ему меньше чем 0 лет?
MC>По ходу я обычно не представляю методы . Я делаю методы. Так если у меня состояние обьекта может сломаться если я не проконтролирую что туда присваеваеться, то я делаю специальный метод SetName. И там уже кидаю ексепшен. Но это все мое ИМХО. Мне интерсно ваше .
Мое мнение такое, что exception в setter'ах это нормально.
Другой вопрос как далеко можно зайти в проверках, но стандартные проверки может ли данное значение быть установлено, думаю стоит размещать в сеттерах.
Я повторюсь: не всегда внутреннее состояние объекта может быть доступно из вне.
Как пример: pattern State
Когда вам приходит объект в каком то состоянии и вы пытаетесь его использовать не правильным образом
Здравствуйте, 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...
}
Так же как для таких методов 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.
Здравствуйте, Mike Chaliy, Вы писали:
MC>Здравствуйте, C...R...a...S...H, Вы писали:
CRA>>Последний пример я думаю очень показательный.
MC>Жаль что вы не ответили на вопросы.... Если вам охота примеров от Майкрософт, то зайдите в любой контрол. Весь дизайнер на этом построен.
Думаю ответ был дан:
The object's current state does not allow this property to be set.
То есть при не правильном использовании объекта, он может матюкаться экшепшанапи даже при установке свойств.
Здравствуйте, 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-а.
Здравствуйте, C...R...a...S...H, Вы писали:
CRA>Думаю ответ был дан:
CRA>
CRA>The object's current state does not allow this property to be set.
CRA>То есть при не правильном использовании объекта, он может матюкаться экшепшанапи даже при установке свойств.
Тоесть если я вам приведу пример где проверка и исключение делаеться на вызов, то вы тоже безаговорочно примите? Ну или давайте по другому. Вы уверены что все что сделано в фремворке идеологически правильно? Вы уверены что это небыло исключением из идеологии?
MC>Тоесть если я вам приведу пример где проверка и исключение делаеться на вызов, то вы тоже безаговорочно примите? Ну или давайте по другому. Вы уверены что все что сделано в фремворке идеологически правильно? Вы уверены что это небыло исключением из идеологии?
Вот вы задумайтесь.
У вас есть объект состояниме которого вы не управляете.
Тоже самое соединение с другим серверм.
Вы его открывает и с ним работаете.
Через некоторое время соединение отрубается, но вы об этом пока не знаете, а просто пытаетесь установить размер пакета для пересылки данных.
Как должен вести себя объект в таком случае?
Здравствуйте, Mike Chaliy, Вы писали:
MC>Интерсно мнение, может ли идеологически сеттер кидать исключение?
MC>Мое ИМХО сеттер не должен кидать никаких исключений. Валидация данных должна проиходить на момент дейтсвия.
Нужно!!!
1)Объект должен поддерживать только корректное состояние, а не быть своего рода свалкой.
2)При твоём подходе — get должен относиться к моменту действия.
Если такового не будет, то вообще лажа, тобишь, появляется вероятность того, что что сущности которые связаны с твоим Person могут оперировать не допустимыми данными.
3)На момент опрашивания состояния объекта(дёрнуть get) — не желательно кидать исключение и производить какие то действия.
По крайней мере разработчик, который будет использовать твой Person мягко говоря удивиться — такому поведению
4)Как дебажить это дело собираешься? Задал возраст равным -1 и пошёл процесс, после этого ты опросил Person и получил исключение
и хочется же узнать, откуда взялся -1 а в StackTrace уже и в помине нет места, в котором задавался возраст равным -1.
5)Если провалидируешь возраст на сеттере то ты это сделаешь в одном месте!!!!!!!
А если на момент совершения действия, то успевай только отслеживать в каких местах используется возраст и расставлять перед вызовами метод аля ValidateAge(). А это уже COPY+PASTE.
6) Модульное тестирование при этом усложняется.
А какие же плюсы во всём этом, дай подумать ...Хм ... Что то не видать!
Здравствуйте, 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, но мы люди не гордые... Инфа полезней, так что проглотим.
Здравствуйте, kisel, Вы писали:
>>>Здравствуйте, Mike Chaliy, Вы писали:
K>5 аргумент не считается, забыл что у нас же предполагается валидировать на get-е
Не-не, я нигде не прдлагал валидировать в геттере. Геттеры по гаидлайнам не должны кидать ексепшены, как и констуркторы собсно. Так что ваше замечание вполне валидно и я на него даже ответил .
Здравствуйте, Mike Chaliy, Вы писали: MC>Я же не советов просил. Тем более меня слегка удивляет пренебрежительное повествование вас и rsn81, но мы люди не гордые... Инфа полезней, так что проглотим.
Так мы любя ... Хорошо, что не гордый ...
По поводу того, что должно быть свойство Age и метод SetAge — как то сложновато закрутил.Код должен быть — friendly.
Если бы мне пришлось юзать этот классец, то первая мысль пришла бы в голову, зачему 2 метода нужны (свойство — это всего лишь 2 сгруппированных метода, может быть и один).
У меня бы мозг закипел и подумал про себя — "снова какой-то индусский код подсунули "
Здравствуйте, Mike Chaliy, Вы писали:
MC>Не-не, я нигде не прдлагал валидировать в геттере. Геттеры по гаидлайнам не должны кидать ексепшены, как и констуркторы собсно. Так что ваше замечание вполне валидно и я на него даже ответил .
Выделенное — что за гайдлайны такие?
Здравствуйте, rsn81, Вы писали:
R>Здравствуйте, Mike Chaliy, Вы писали:
MC>>Не-не, я нигде не прдлагал валидировать в геттере. Геттеры по гаидлайнам не должны кидать ексепшены, как и констуркторы собсно. Так что ваше замечание вполне валидно и я на него даже ответил . R>Выделенное — что за гайдлайны такие?
Хотя я там слишком жестко написал, в гаидлайнах речь идет про "хотелось бы что бы не кидали". "не должны" лучше читать как "не хотлоесь бы". Но так как весь суть разговора идет про идеолгическую часть, которая по необходисомти может быть попрана. То ИМХО вполне допустимо использовать черное и белое.