А>а что он рекомендует в случае перегруженных public функциях (спасибо хейлсбергу за отсутствие параметров по умолчанию ) которые как правило реализуются одной, самой "полной", из них?
Ждать С# 4
Где проверять контракты методов?
От:
Аноним
Дата:
10.07.09 08:58
Оценка:
Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере
publicvoid Do(int arg1, string arg2)
{
// здесь?double arg3 = ...;
_Do(arg1, arg2, arg3);
}
privatevoid _Do(int arg1, string arg2, double arg3)
{
// или может лучше здесь? ...
}
ну и в других, подобных случаях (особенно нужно учесть, что _Do может быть вызвана где-то еще из публичных методов класса
Здравствуйте, Аноним, Вы писали:
А>Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере
А>
Здравствуйте, Аноним, Вы писали:
А>Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере
... А>ну и в других, подобных случаях (особенно нужно учесть, что _Do может быть вызвана где-то еще из публичных методов класса
У Макконнелла есть понятие "баррикады" (снаружи данные считаются грязными, внутри — чистыми):
"Методы с внешней стороны баррикады должны использовать обработчики ошибок, поскольку небезопасно делать любые предположения о данных. Методы внутри баррикад должны использовать утверждения, так как данные, переданные им, считаются проверенными при прохождении баррикады."
Вполне разумно очищать данные на входе в публичные методы, а в приватные методы передавать уже гарантированно корректные данные, на всякий случай вставив на входе утверждения (assertions).
Здравствуйте, Аноним, Вы писали:
А>Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере
А>
А>ну и в других, подобных случаях (особенно нужно учесть, что _Do может быть вызвана где-то еще из публичных методов класса
Именно в отквоченном примере — в _Do, к гадалке не ходи. Иначе начнется копи-паст и все такое, ну или методы типа CheckArg1(), CheckArg2(), CheckArg1AndArg2()... что тоже в целом не айс.
НО! Допустим arg3 вовсе не double, а датасет с 20-мин. извлечением данных. Тогда, разумеется, arg1, arg2 надо проверить ДО того как, что бы не терять время на заполнение датасета.
В общем — все как всегда, нет ни правильных, ни не правильных решений. Есть лишь уместные в данной задаче и не очень.
Re[2]: Где проверять контракты методов?
От:
Аноним
Дата:
10.07.09 09:24
Оценка:
Здравствуйте, andy1618, Вы писали:
A>Вполне разумно очищать данные на входе в публичные методы, а в приватные методы передавать уже гарантированно корректные данные, на всякий случай вставив на входе утверждения (assertions).
(не знаю знакомы ли вы с библиотекой Code Contracts, но все же хотелось бы на ее примере если не сложно)
правильно ли я понимаю, что нужно делать так:
Здравствуйте, gandjustas, Вы писали:
G>Framework Design Guidelines рекомендует проверять контракты в публичных методах
а что он рекомендует в случае перегруженных public функциях (спасибо хейлсбергу за отсутствие параметров по умолчанию ) которые как правило реализуются одной, самой "полной", из них?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, gandjustas, Вы писали:
G>>Framework Design Guidelines рекомендует проверять контракты в публичных методах
А>а что он рекомендует в случае перегруженных public функциях (спасибо хейлсбергу за отсутствие параметров по умолчанию ) которые как правило реализуются одной, самой "полной", из них?
Аналогично.
Но надо учитывать что Framework Design != Application Design, возможно в вашем случае будет удобно сделать наоборот
Здравствуйте, Аноним, Вы писали: А>(не знаю знакомы ли вы с библиотекой Code Contracts, но все же хотелось бы на ее примере если не сложно) А>правильно ли я понимаю, что нужно делать так: А>
А почему внутри должны использоваться ассерты, а не те же самые предусловия?
Предусловия должны быть во обоих методах, другое дело в том, какие контракты вы хотите оставить в release-сборках.
Лично я не использую контракты в релизе, поэтому в public surface делаю обычные if-then-throw проверки, а внутри — Requires:
public void Do(int arg1, string arg2)
{
if (arg1 < 0)
throw new ArgumentOutOfRangeException("arg1");
if (arg2 == null)
throw new ArgumentNullException("arg2");
Contract.EndContractBlock();
double arg3 = ...;
_Do(arg1, arg2, arg3);
}
private void _Do(int arg1, string arg2, double arg3)
{
Contract.Requires(arg1 >= 0);
Contract.Requires(arg2 != null);
Contract.Requires(arg3 != 0);
...
}
if-then-throw отлично распознаётся верификатором
Вообще есть три сценария использования контрактов, смотрите user manual.
p.s. Requires(arg3 != 0) в _Do может быть доказано верификатором, например, если Вы его берёте из метода, Ensures которого подходит под Requires.
Re[4]: Где проверять контракты методов?
От:
Аноним
Дата:
10.07.09 12:25
Оценка:
Здравствуйте, Пельмешко, Вы писали:
П>Лично я не использую контракты в релизе, поэтому в public surface делаю обычные if-then-throw проверки, а внутри — Requires:
а почему? ведь теряется весь смысл, и стройность приложения, от использования контрактов?
контракты ведь можно настроить на ассерты в дебаге, а в релизе на эксепшены.
Здравствуйте, Аноним, Вы писали: А>а почему? ведь теряется весь смысл, и стройность приложения, от использования контрактов? А>контракты ведь можно настроить на ассерты в дебаге, а в релизе на эксепшены. А>
Не теряется смысл, теряется зависимость от Microsoft.Contracts.dll
Стройность — если Вы под этим имеете ввиду декларативность, то да, теряется.
Ещё раз говорю, usage guidelines в мануале описывает 3 сценария, я лишь использую один из них.
G>>Framework Design Guidelines рекомендует проверять контракты в публичных методах А>а что он рекомендует в случае перегруженных public функциях (спасибо хейлсбергу за отсутствие параметров по умолчанию ) которые как правило реализуются одной, самой "полной", из них?
Незнаю насчет "него", но лично я стараюсь вообще в public-функциях основной функционал не реализовывать, на мой взгляд это окупается при рефакторинге.
--
Sergey Chadov
... << RSDN@Home 1.2.0 alpha rev. 685>>
Re[3]: offtop: дефолтные параметры - зло
От:
Аноним
Дата:
10.07.09 17:06
Оценка:
Здравствуйте, Аноним, Вы писали:
А>(спасибо хейлсбергу за отсутствие параметров по умолчанию )
Уж сколько раз спотыкался, что лучше б их нигде не было. Код стройнее, пусть и печатать чуть больше приходится.
Re[4]: offtop: дефолтные параметры - зло
От:
Аноним
Дата:
10.07.09 17:36
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Уж сколько раз спотыкался, что лучше б их нигде не было. Код стройнее, пусть и печатать чуть больше приходится.
стройнее для того кто их не смог "асилить" (хотя это элементано)?
Здравствуйте, andy1618, Вы писали:
А>>Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере
A>Вполне разумно очищать данные на входе в публичные методы, а в приватные методы передавать уже гарантированно корректные данные, на всякий случай вставив на входе утверждения (assertions).
прочитал три раза и все равно не понял, особенно с учетом реХакторинга.
можно отразить примером ваш принцип использования контрактов?
Re[5]: offtop: дефолтные параметры - зло
От:
Аноним
Дата:
10.07.09 20:20
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Аноним, Вы писали:
А>>Уж сколько раз спотыкался, что лучше б их нигде не было. Код стройнее, пусть и печатать чуть больше приходится.
А>стройнее для того кто их не смог "асилить" (хотя это элементано)?
Дефолтные параметры — это coding style, а не скилзы, что там "асиливать"?
А>а копи-паст из ё вей?
Если в коде начинается копи-паст — самое время подумать. Например, о рефакторинге, полиморфизме, шаблонной параметризации и т.п.
Виноват, "данным подходом" я назвал предложенный andy1618 и другими подход с проверкой контрактов в открытых методах.
А>особенно с учетом реХакторинга.
Рехакторингом я прорсто называю любой рефакторинг. Словечко услышал от коллегм и уж больно оно мне понравилось.
А>можно отразить примером ваш принцип использования контрактов?
Суть проста: если вам понятен подход "проверка контрактов только в открытых методах", то должен быть понятен и подход "проверка во всех методах, не смотря на область видимости".
Help will always be given at Hogwarts to those who ask for it.
Re[6]: offtop: дефолтные параметры - зло
От:
Аноним
Дата:
11.07.09 08:34
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Дефолтные параметры — это coding style, а не скилзы, что там "асиливать"?
это уже не важно, т.к. их придется "асилить" в C# 4.0
А>Если в коде начинается копи-паст — самое время подумать. Например, о рефакторинге, полиморфизме, шаблонной параметризации и т.п.
_FR>Суть проста: если вам понятен подход "проверка контрактов только в открытых методах", то должен быть понятен и подход "проверка во всех методах, не смотря на область видимости".
Согласен, второй подход безусловно правилен и работоспособен, но код приватных методов может оказаться сильно загромождён проверками, и в итоге может оказаться, что "за деревьями не видно леса".
Здравствуйте, andy1618, Вы писали:
_FR>>Суть проста: если вам понятен подход "проверка контрактов только в открытых методах", то должен быть понятен и подход "проверка во всех методах, не смотря на область видимости".
A>Согласен, второй подход безусловно правилен и работоспособен, но код приватных методов может оказаться сильно загромождён проверками, и в итоге может оказаться, что "за деревьями не видно леса".
Загромождённости нет, так как проверки проводятся в начале метода и легко на глаз отличимы от тела. Писать проверки — да, приходится. Меня выручают любимые сниппеты.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Аноним, Вы писали:
А>(не знаю знакомы ли вы с библиотекой Code Contracts, но все же хотелось бы на ее примере если не сложно) А>правильно ли я понимаю, что нужно делать так:
А>
А>public void Do(int arg1, string arg2)
А>{
А> Contract.Requires(arg1 >= 0);
А> Contract.Requires<ArgumentNullException>(arg2 != null, "arg2");
А> double arg3 = ...; // а как быть здесь? кто проверяет arg3 ?
А> _Do(arg1, arg2, arg3);
А>}
А>
К сожалению, пока с Code Contracts не разбирался, но по виду вполне правильно всё написано.
А по поводу arg3 — перед вызовом _Do должна быть уверенность, что arg3 корректен и, соответственно, можно на него Assert поставить. Если же уверенности нет — надо сделать, чтобы она была (if-then-throw и т.п.).
Здравствуйте, andy1618, Вы писали:
A>А по поводу arg3 — перед вызовом _Do должна быть уверенность, что arg3 корректен и, соответственно, можно на него Assert поставить. Если же уверенности нет — надо сделать, чтобы она была (if-then-throw и т.п.).
Я не понимаю, почему надо ассертом проверять параметр перед вызовом метода , если свои параметры должен проверять сам метод — предусловиями (которые по сути те же ассерты).
Contact.Assert нужен только для утверждений по телу метода (в отличие от других контрактных методов он может располагаться где угодно в методе и в любом порядке), не надо им делать работу Requires.
Re[5]: Где проверять контракты методов?
От:
Аноним
Дата:
13.07.09 08:55
Оценка:
Здравствуйте, Пельмешко, Вы писали:
П>Я не понимаю, почему надо ассертом проверять параметр перед вызовом метода , если свои параметры должен проверять сам метод — предусловиями (которые по сути те же ассерты). П>Contact.Assert нужен только для утверждений по телу метода (в отличие от других контрактных методов он может располагаться где угодно в методе и в любом порядке), не надо им делать работу Requires.
как я понял из первого ответа, данный вариант преложен исходя из того, что private методы вызывают с данными только из доверенных источников, следовательно Require там нет смысла ставить. а ассерты нужны в момент отладки, для проверки логики.
Здравствуйте, Аноним, Вы писали:
А>как я понял из первого ответа, данный вариант преложен исходя из того, что private методы вызывают с данными только из доверенных источников, следовательно Require там нет смысла ставить. а ассерты нужны в момент отладки, для проверки логики.
Причём здесь роль скорее даже не столько в проверке логики (ибо хватит и ассёрта в теле приватного метода), сколько в документировании кода: явно вписав Assert перед вызовом, автор кода сообщает будущим читателям, что вопрос корректности аргумента был "тщательно проработан"