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