Re[3]: Где проверять контракты методов?
От: QrystaL Украина  
Дата: 10.07.09 09:51
Оценка: 1 (1) +1
А>а что он рекомендует в случае перегруженных public функциях (спасибо хейлсбергу за отсутствие параметров по умолчанию ) которые как правило реализуются одной, самой "полной", из них?

Ждать С# 4
Где проверять контракты методов?
От: Аноним  
Дата: 10.07.09 08:58
Оценка:
Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере

public void Do(int arg1, string arg2)
{
    // здесь?    
    double arg3 = ...;
    _Do(arg1, arg2, arg3);
}

private void _Do(int arg1, string arg2, double arg3)
{
    // или может лучше здесь?    ...
}


ну и в других, подобных случаях (особенно нужно учесть, что _Do может быть вызвана где-то еще из публичных методов класса
Re: Где проверять контракты методов?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.07.09 09:07
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере


А>
А>public void Do(int arg1, string arg2)
А>{
А>    // здесь?    
А>    double arg3 = ...;
А>    _Do(arg1, arg2, arg3);
А>}

А>private void _Do(int arg1, string arg2, double arg3)
А>{
А>    // или может лучше здесь?    ...
А>}


А>ну и в других, подобных случаях (особенно нужно учесть, что _Do может быть вызвана где-то еще из публичных методов класса


Framework Design Guidelines рекомендует проверять контракты в публичных методах
Re: Где проверять контракты методов?
От: andy1618 Россия  
Дата: 10.07.09 09:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере

...
А>ну и в других, подобных случаях (особенно нужно учесть, что _Do может быть вызвана где-то еще из публичных методов класса

У Макконнелла есть понятие "баррикады" (снаружи данные считаются грязными, внутри — чистыми):

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


Вполне разумно очищать данные на входе в публичные методы, а в приватные методы передавать уже гарантированно корректные данные, на всякий случай вставив на входе утверждения (assertions).
Re: Где проверять контракты методов?
От: Smarty Россия  
Дата: 10.07.09 09:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере


А>
А>public void Do(int arg1, string arg2)
А>{
А>    // здесь?    
А>    double arg3 = ...;
А>    _Do(arg1, arg2, arg3);
А>}

А>private void _Do(int arg1, string arg2, double arg3)
А>{
А>    // или может лучше здесь?    ...
А>}


А>ну и в других, подобных случаях (особенно нужно учесть, что _Do может быть вызвана где-то еще из публичных методов класса


Именно в отквоченном примере — в _Do, к гадалке не ходи. Иначе начнется копи-паст и все такое, ну или методы типа CheckArg1(), CheckArg2(), CheckArg1AndArg2()... что тоже в целом не айс.
НО! Допустим arg3 вовсе не double, а датасет с 20-мин. извлечением данных. Тогда, разумеется, arg1, arg2 надо проверить ДО того как, что бы не терять время на заполнение датасета.
В общем — все как всегда, нет ни правильных, ни не правильных решений. Есть лишь уместные в данной задаче и не очень.
Re[2]: Где проверять контракты методов?
От: Аноним  
Дата: 10.07.09 09:24
Оценка:
Здравствуйте, andy1618, Вы писали:

A>Вполне разумно очищать данные на входе в публичные методы, а в приватные методы передавать уже гарантированно корректные данные, на всякий случай вставив на входе утверждения (assertions).


(не знаю знакомы ли вы с библиотекой 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);
}

private void _Do(int arg1, string arg2, double arg3)
{
    Contract.Assert(arg1 >= 0);
    Contract.Assert(arg2 != null);
    Contract.Assert(arg3 != 0);    

    ...
}
Re[2]: Где проверять контракты методов?
От: Аноним  
Дата: 10.07.09 09:29
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Framework Design Guidelines рекомендует проверять контракты в публичных методах


а что он рекомендует в случае перегруженных public функциях (спасибо хейлсбергу за отсутствие параметров по умолчанию ) которые как правило реализуются одной, самой "полной", из них?
Re[3]: Где проверять контракты методов?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.07.09 09:34
Оценка:
Здравствуйте, Аноним, Вы писали:

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


G>>Framework Design Guidelines рекомендует проверять контракты в публичных методах


А>а что он рекомендует в случае перегруженных public функциях (спасибо хейлсбергу за отсутствие параметров по умолчанию ) которые как правило реализуются одной, самой "полной", из них?


Аналогично.

Но надо учитывать что Framework Design != Application Design, возможно в вашем случае будет удобно сделать наоборот
Re[3]: Где проверять контракты методов?
От: Пельмешко Россия blog
Дата: 10.07.09 12:10
Оценка:
Здравствуйте, Аноним, Вы писали:
А>(не знаю знакомы ли вы с библиотекой Code Contracts, но все же хотелось бы на ее примере если не сложно)
А>правильно ли я понимаю, что нужно делать так:
А>
А>private void _Do(int arg1, string arg2, double arg3)
А>{
А>    Contract.Assert(arg1 >= 0);
А>    Contract.Assert(arg2 != null);
А>    Contract.Assert(arg3 != 0);    

А>    ...
А>}
А>

А почему внутри должны использоваться ассерты, а не те же самые предусловия?

Предусловия должны быть во обоих методах, другое дело в том, какие контракты вы хотите оставить в 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:

а почему? ведь теряется весь смысл, и стройность приложения, от использования контрактов?
контракты ведь можно настроить на ассерты в дебаге, а в релизе на эксепшены.
Re[5]: Где проверять контракты методов?
От: Пельмешко Россия blog
Дата: 10.07.09 13:20
Оценка:
Здравствуйте, Аноним, Вы писали:
А>а почему? ведь теряется весь смысл, и стройность приложения, от использования контрактов?
А>контракты ведь можно настроить на ассерты в дебаге, а в релизе на эксепшены.
А>

Не теряется смысл, теряется зависимость от Microsoft.Contracts.dll
Стройность — если Вы под этим имеете ввиду декларативность, то да, теряется.

Ещё раз говорю, usage guidelines в мануале описывает 3 сценария, я лишь использую один из них.
Re[3]: Где проверять контракты методов?
От: Sergey Chadov Россия  
Дата: 10.07.09 15:22
Оценка:
Здравствуйте, <Аноним>, Вы писали:


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
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Уж сколько раз спотыкался, что лучше б их нигде не было. Код стройнее, пусть и печатать чуть больше приходится.


стройнее для того кто их не смог "асилить" (хотя это элементано)?

а копи-паст из ё вей?
Re[2]: Где проверять контракты методов?
От: _FRED_ Черногория
Дата: 10.07.09 18:03
Оценка:
Здравствуйте, andy1618, Вы писали:

А>>Вопрос: где лучше (правильно) проверять контракты методов класса (в частности аргументов метода) на следующем примере


A>Вполне разумно очищать данные на входе в публичные методы, а в приватные методы передавать уже гарантированно корректные данные, на всякий случай вставив на входе утверждения (assertions).


Мне такой подход не нравится следующим следствием: при рефакторинге, из-за того, что где-то проверка осуществляется одним путём, а где-то другим, приходится делать больше исправлений. Гораздо преще проверять одинаково везде, где того требуют условия вызова, вне зависимости от области видимости метода. При данном подходе, получается, что открытый метод должен проверять контракт закрытого, то етсь увеличивается связанность, из-за которой и берутся сложности рехакторинга©.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Где проверять контракты методов?
От: Аноним  
Дата: 10.07.09 20:05
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Мне такой подход не нравится следующим следствием: при рефакторинге, из-за того, что где-то проверка осуществляется одним путём, а где-то другим, приходится делать больше исправлений. Гораздо преще проверять одинаково везде, где того требуют условия вызова, вне зависимости от области видимости метода. При данном подходе, получается, что открытый метод должен проверять контракт закрытого, то етсь увеличивается связанность, из-за которой и берутся сложности рехакторинга©.


прочитал три раза и все равно не понял, особенно с учетом реХакторинга.
можно отразить примером ваш принцип использования контрактов?
Re[5]: offtop: дефолтные параметры - зло
От: Аноним  
Дата: 10.07.09 20:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>Уж сколько раз спотыкался, что лучше б их нигде не было. Код стройнее, пусть и печатать чуть больше приходится.


А>стройнее для того кто их не смог "асилить" (хотя это элементано)?


Дефолтные параметры — это coding style, а не скилзы, что там "асиливать"?

А>а копи-паст из ё вей?


Если в коде начинается копи-паст — самое время подумать. Например, о рефакторинге, полиморфизме, шаблонной параметризации и т.п.
Re[4]: Где проверять контракты методов?
От: _FRED_ Черногория
Дата: 11.07.09 03:15
Оценка:
Здравствуйте, Аноним, Вы писали:

_FR>>Мне такой подход не нравится следующим следствием: при рефакторинге, из-за того, что где-то проверка осуществляется одним путём, а где-то другим, приходится делать больше исправлений. Гораздо преще проверять одинаково везде, где того требуют условия вызова, вне зависимости от области видимости метода. При данном подходе, получается, что открытый метод должен проверять контракт закрытого, то етсь увеличивается связанность, из-за которой и берутся сложности рехакторинга©.


А>прочитал три раза и все равно не понял,


Виноват, "данным подходом" я назвал предложенный 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

А>Если в коде начинается копи-паст — самое время подумать. Например, о рефакторинге, полиморфизме, шаблонной параметризации и т.п.


расскажите это разработчикам FCL
Re[5]: Где проверять контракты методов?
От: andy1618 Россия  
Дата: 13.07.09 07:50
Оценка:
_FR>Суть проста: если вам понятен подход "проверка контрактов только в открытых методах", то должен быть понятен и подход "проверка во всех методах, не смотря на область видимости".

Согласен, второй подход безусловно правилен и работоспособен, но код приватных методов может оказаться сильно загромождён проверками, и в итоге может оказаться, что "за деревьями не видно леса".
Re[6]: Где проверять контракты методов?
От: _FRED_ Черногория
Дата: 13.07.09 08:09
Оценка:
Здравствуйте, andy1618, Вы писали:

_FR>>Суть проста: если вам понятен подход "проверка контрактов только в открытых методах", то должен быть понятен и подход "проверка во всех методах, не смотря на область видимости".


A>Согласен, второй подход безусловно правилен и работоспособен, но код приватных методов может оказаться сильно загромождён проверками, и в итоге может оказаться, что "за деревьями не видно леса".


Загромождённости нет, так как проверки проводятся в начале метода и легко на глаз отличимы от тела. Писать проверки — да, приходится. Меня выручают любимые сниппеты.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Где проверять контракты методов?
От: andy1618 Россия  
Дата: 13.07.09 08:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>(не знаю знакомы ли вы с библиотекой 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 и т.п.).
Re[4]: Где проверять контракты методов?
От: Пельмешко Россия blog
Дата: 13.07.09 08:45
Оценка:
Здравствуйте, andy1618, Вы писали:

A>А по поводу arg3 — перед вызовом _Do должна быть уверенность, что arg3 корректен и, соответственно, можно на него Assert поставить. Если же уверенности нет — надо сделать, чтобы она была (if-then-throw и т.п.).


Я не понимаю, почему надо ассертом проверять параметр перед вызовом метода , если свои параметры должен проверять сам метод — предусловиями (которые по сути те же ассерты).
Contact.Assert нужен только для утверждений по телу метода (в отличие от других контрактных методов он может располагаться где угодно в методе и в любом порядке), не надо им делать работу Requires.
Re[5]: Где проверять контракты методов?
От: Аноним  
Дата: 13.07.09 08:55
Оценка:
Здравствуйте, Пельмешко, Вы писали:

П>Я не понимаю, почему надо ассертом проверять параметр перед вызовом метода , если свои параметры должен проверять сам метод — предусловиями (которые по сути те же ассерты).

П>Contact.Assert нужен только для утверждений по телу метода (в отличие от других контрактных методов он может располагаться где угодно в методе и в любом порядке), не надо им делать работу Requires.

как я понял из первого ответа, данный вариант преложен исходя из того, что private методы вызывают с данными только из доверенных источников, следовательно Require там нет смысла ставить. а ассерты нужны в момент отладки, для проверки логики.
Re[6]: Где проверять контракты методов?
От: andy1618 Россия  
Дата: 13.07.09 09:11
Оценка:
Здравствуйте, Аноним, Вы писали:

А>как я понял из первого ответа, данный вариант преложен исходя из того, что private методы вызывают с данными только из доверенных источников, следовательно Require там нет смысла ставить. а ассерты нужны в момент отладки, для проверки логики.


Причём здесь роль скорее даже не столько в проверке логики (ибо хватит и ассёрта в теле приватного метода), сколько в документировании кода: явно вписав Assert перед вызовом, автор кода сообщает будущим читателям, что вопрос корректности аргумента был "тщательно проработан"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.