Design by Contract

2,113 views
2,112 views

Published on

- Базовые понятия контрактного программирования
- Практические аспекты
- Библиотека Code Contracts
- Ограничения контрактов

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,113
On SlideShare
0
From Embeds
0
Number of Embeds
1,527
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Такие слова, как «формализация» или «спецификация» чужды и страшны большинству разработчиков. Сразу же возникает вопрос: а стоит ли затевать весь этот сыр-бор ради этого? Чем не подходят старые, проверенные временем практики, без всяких там контрактов?
  • А что если описать отношения между классом (или интерфейсом) и его клиентами более формальным образом.Например, можно сказать, что я сделаю свою работу, но только в том случае, если свою работу сделает вызывающий код.Таким образом, мы четко разделим отношения класса и его клиенты; каждый из них будет точно знать, на что рассчитывать от другой стороны и не будет перепроверять это по десять раз.Кстати, обратите внимание, что я не говорю о тотальной формализации отношений, зачастую достаточно разделить эти обязанности в вашей голове, чтобы такое разделение нашло отражение в вашем коде и дизайне.Но прежде чем переходить к способам разделения ответственностей, давайте рассмотрим еще одну важную характеристику.Я думаю, что многие разработчики спорят друг с другом во время код или дизайн ревью (или с представителями отдела качества) о том, содержит ли баг некоторый фрагмент кода или нет.
  • Сейчас существует огромное множество различных паттернов, принципов, идиом, которые должны помочь в создании хорошего дизайна. Я ничего не имею, например, против принципов SOLID, но у меня есть совет, как их лучше запомнить и, главное, как ими лучше пользоваться на практике.На самом деле, контрактное программирование (прошу, не путайте с конкретными библиотеками, типа Code Contracts) – это отличный инструмент в борьбе за хороший дизайн.Для начала, давайте рассмотрим один из SOLID принципов: принцип замещения Лисков. Именно на нем строится очень важный аспект любой ОО модели, поскольку он лежит в основе полиморфного поведения.Может стоит сказать о том, что в самой навороченной книге по ООП – в книге Бертрана Мейера описано очень мало разных принципов. Из известных есть только Open Closed.
  • Design by Contract

    1. 1. Проектирование по контракту Сергей Тепляков, Visual C# MVP .NET Architect at Luxoft SergeyTeplyakov.blogspot.com
    2. 2. Agenda• Базовые понятия контрактного программирования• Практические аспекты• Библиотека Code Contracts• Ограничения контрактов
    3. 3. ОпределениеПроектирование по контракту(Design by Contract, DbC) – этоформализация отношений междупрограммным компонентом и егоклиентами
    4. 4. А нужно ли это?
    5. 5. Что скажете?public interface IRepository{ Customer GetCustomer(string id); void SaveCustomer(Customer c);}
    6. 6. Стандартное решение• «Комментарии не лгут»• На крайний случай «Use the Source Luke!»
    7. 7. Давайте добавим немного формальности!
    8. 8. О корректности ПО• Код сам по себе, не является корректным или некорректным!• Важна спецификация• «Задокументированный баг – это фича!»
    9. 9. Утверждения в контрактах• Предусловия• Постусловия• Инвариант класса• Утверждения• Инвариант цикла (Eiffel specific)
    10. 10. Внедрение спецификации вкодclass Repository : IRepository{ public Customer GetCustomer(string id) { Contract.Requires(id != null); Contract.Ensures( Contract.Result<Customer>() != null); }}
    11. 11. Нарушения утверждений• Нарушение предусловия – «баг» в клиенте коде• Нарушение постусловия, инварианта или утверждения – «баг» в сервисе
    12. 12. Инструменты DbC• Утверждения• Статический анализатор• Документация (DRY)
    13. 13. Контракты – это общеепонятие, которое покрывает многие известные ОО принципы
    14. 14. Принцип замещения Лисков...если для каждого объекта o1 типа Sсуществует объект o2 типа T такой, что длявсех программ P, определенных в терминах T,поведение P не изменяется при замене o2 на o1,то S является подтипом (subtype) для T.
    15. 15. Принцип замещения Лисков
    16. 16. Метод Add• ICollection.Add• IList.Add• Может ли метод добавлять 2 элемента?• Или не добавлять ни одного?
    17. 17. Правила наследования• Наследник может • ослабевать предусловие • усиливать постусловие• Инварианты суммируются
    18. 18. Сильные и слабые условия• X > 0 (слабее)• X > 5 (сильнее, строже)
    19. 19. Предусловие и наследование
    20. 20. Отношение между типами
    21. 21. Ковариантность по типувозвращаемого значения
    22. 22. КонтравариантностьAction<in T>static void Foo(object obj) { }// Контравариантность аргументов:// предусловие делегата Action<object> слабее// предусловия Action<string>,// поскольку typeof(object) > typeof(string)Action<string> action1 = Foo;// ИлиAction<string> action2 = new Action<object>(Foo);action1("Hello Foo!");
    23. 23. Ковариантность Func<out T>static string Boo() { return "Boo"; }// Ковариантность возвращаемого значения:// постусловие делегата Func<string> сильнее// постусловия Func<object>,// поскольку typeof(string) < typeof(object)Func<object> func1 = Boo;// ИлиFunc<object> func2 = new Func<string>(Boo);
    24. 24. Ковариантностьисключенийclass Base {public:virtual void Foo() throw(std::exception) {}};class Derived : public Base {public:/*override*/ void Foo() throw(std::logic_error) {}};
    25. 25. Принцип самурая
    26. 26. Мониторинг утвержденийво время выполнения• Уровни утверждений • None • Requires • Ensures • Full• Assert on Contract Failures
    27. 27. Утверждения и внешниеданные
    28. 28. Контракты vs Защитноепрограммирование Проверка Проверка при предусловий каждом (2 открытых обращении к метода) полю (27 мест!)
    29. 29. Code Contracts• Частичная поддержка в .NET 4.0• Устанавливается отдельно: • Статический анализатор • Rewriter • Генератор документации
    30. 30. Вернемся к методу Add// From mscorlib.Contracts.dll[ContractClassFor(typeof (ICollection<>))]internal abstract class ICollectionContract<T> : ICollection<T>{ public void Add(T item) { // Исходный контракт Contract.Ensures(Count >= Contract.OldValue<int>(Count), "this.Count >= Contract.OldValue(this.Count)"); // Мы могли бы добавить! Contract.Ensures(Contains(item), "Contains(item) should be true!"); }}
    31. 31. Адаптация существующегокода • Уже есть класс Guard? • Добавляем атрибут и получаем предусловие!
    32. 32. Code Contracts • Contract.Requires • Contract.Ensures • Contract.Invariant • Contract.Assert/Assume
    33. 33. Альтернативная проверкапредусловий public class SimpleClass { public int Foo(string s) { if (s == null) throw new ArgumentNullException("s"); Contract.EndContractBlock(); return s.Length; } }
    34. 34. Альтернативная проверкапредусловий public static class Guard { [ContractArgumentValidatorAttribute] public static void IsNotNull<T>(T t) where T : class { if (t == null) throw new ArgumentNullException("t"); Contract.EndContractBlock(); } }
    35. 35. Ограничения DbC• Аккуратнее со статическим анализатором!• Не переусердствуйте в формализации• Частичная поддержка Code Contracts в .NET Framework
    36. 36. Важнейшие принципы DbC• Разделение ответственности• Упрощение обязанностей• Обобщение существующих понятий• Формализация отношений
    37. 37. Дополнительные материалы• Бертран Мейер, “Объектно-ориентированное конструирование программных систем”• С. Тепляков, “Проектирование по контракту”, RSDN Magazine #1- 2010• Programming Stuff. “Альтернативная проверка предусловий в Code Contracts”• Programming Stuff. “Принцип замещения Лисков и контракты”• Programming Stuff. “Принцип самурая”• Programming Stuff. “Как не надо писать код”• Александр Бындю. “Дополнение к LSP”
    38. 38. Спасибо за внимание • Сергей Тепляков, Visual C# MVP • .NET Architect at Luxoft • Sergey.Teplyakov@gmail.com• http://sergeyteplyakov.blogspot.com/

    ×