Pull to refresh

Comments 10

Можно в двух словах смысл контрактов на примерах? С Мейером лично общался, Эйфель щупал, но в среде .NET на реальных задачах — профита не нашёл (но и глубоко не искал). Т.е. с простыми случаями типа коллекций — понятно. Но именно в мире ынтырпрайза, на примерах ынтырпрайза? Когда у меня есть метод начисления заработной платы для сотрудника, где сотрудник и его должность — это параметры метода начисления денег, которое происходит на счёт сотрудника, являющийся его свойством. Что здесь описать в контракте? Убедиться, что баланс счёта сотрудника вырос на размер зп, дёрнув при этом БД и пройдясь по ассоциациям? Если да, то чем это отличается от покрытия этого же кода — тестами?
В моем энтерпрайзе мне постоянно приходится думать над следующим: я вижу метод, принимающий некоторый объект. Обычно, подсовывать null туда нельзя, но в редких случаях, и если очень хочется то можно. Т.е. чтобы понять, что мне нужно сделать, мне нужно читать код, а там можем быть полотно спагетти-кода на пару экранов.

Тоже самое касается и постусловий. Если класс, у которого есть коллекция в виде какого-то свойства. В большинство людей используют пустую коллекцию, и никогда не возвращают null, но это далеко не всегда. Постусловие в этом плане четко скажет, чего ожидать от этого свойства (или возвращающего значения метода).

Да, в большинстве случаев более или менее сложные предусловия и постусловия живут в библиотеках, но некоторые бизнес-правила тоже можно формализовать. В целом так: исключения типа ArgumentNullException, InvalidArgumentEception, ArgumentOutOfRangeExcpetion все заменяются на соответствующие предусловия (ведь все эти исключения, на самом деле выбрасываются при нарушении предусловий). С постусловиями и инвариантами сложнее, поскольку они внутренние по отношению к вызывающему коду.

В целом, рассмотрение взаимоотношений классов через призму контрактов позволяет мне понять, сферы ответственности обоих классов, и кто кому что должен. Опять таки, если поднимутся вопросы с некоторыми принципами, типа Liskov Substitution Principle, то контракты здесь очень ок.

Ну и очень ОК использование контрактов для интерфейсов, понять семантику которых только исходя из документации весьма сложно.
>> Обычно, подсовывать null туда нельзя,
Э-хе-хех…
99% предусловий, которые я видел — это проверки на notnull. Что мешало MS сделать ссылочные типы НЕ допускающие null в качестве значения?
Да, согласен. Можно юзать что-то типа F#-а, там все референс-типы non-nullable. А из ОО языков, кажется только Eiffel поддерживает non-nullability на уровне языка.
угу. тока для нормального интерпрайз проэкта — Ф-шарп илиЭйфил — это совсем не вариант, ты ж понимаешь…
Нет, в контракте описывается, что сотрудник и должность должны быть ненулевыми, и что после выполнения метода сотрудник все еще остается ненулевым.
Насчёт тестов — да, контракты позволяют писать тесты в декларативной форме. Равно как и не из описания в комментариях, а из утверждений контракта класса понять что он делает, что он требует и что гарантирует. Более явно это преимущество будет после интеграции наработок по Spec# в одну из будущих версий C#.

Также контракты позволяют формировать автоматические тесты, работать по CDD(Contract-Driven Development) (по аналогии с TDD). Под .Net есть интересная разработка «Pex» (идёт вместе с «Moles»), которая учитывает контракты при построении автоматических white-тестов.

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

Под .Net контракты только появились и выгода в их использовании пока ещё не столь очевидна из-за того, что различные инструменты, которые могли бы их использовать в полной мере всё ещё развиваются. Те же наработки для Eiffel-я по непрерывным фоновым автоматическим тестам, предложенями компилятора по исправлению ичастков кода, параллельному программированию, когда котракты выступают в роли механизма синхронизации потоков и пр.

ИМХО при текущей поддержке контрактов в .Net среде их выгодя для Enterprise не столь очевидна, но их следует применять хотя бы для того чтобы писать более обдуманный код, делиться предположениями/ожиданиями реализации с коллегами, которые потом будут переиспользовать ваш класс, да и просто на будущее, т.к. у контрактов очень большие перспективы.
Предусловия: сотрудник и должность не нулевые
Постусловие: счёт сотрудника увеличился (хотя бы не уменьшился)
Инвариант: счёт неотрицательный
UFO just landed and posted this here
У меня последняя версия.

public int Count
{
get
{
// We should add some hints to static checker to eliminate a warning
// Contract.Ensures(Contract.Result() == _backingList.Count);
return _backingList.Count;
}
}


Закомментируйте строку с Contract.Ensures, тогда предупреждение появится, что статик чекер не может гарантировать удовлетворение одного из постусловий.
Sign up to leave a comment.

Articles