38
Проектирование по контракту Сергей Тепляков, Visual C# MVP .NET Architect at Luxoft SergeyTeplyakov.blogspot.com

Design by Contract

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Design by Contract

Проектирование по контракту

Сергей Тепляков, Visual C# MVP.NET Architect at Luxoft

SergeyTeplyakov.blogspot.com

Page 2: Design by Contract

Agenda

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

Page 3: Design by Contract

Определение

Проектирование по контракту (Design by Contract, DbC) – это формализация отношений между программным компонентом и его клиентами

Page 4: Design by Contract

?Анужнолиэто

Page 5: Design by Contract

?Чтоскажете

public interface IRepository{    Customer GetCustomer(string id);    void SaveCustomer(Customer c);}

Page 6: Design by Contract

Стандартноерешение

•«Комментарии не лгут»•На крайний случай «Use the Source Luke!»

Page 7: Design by Contract

Давайтедобавимнемного!формальности

Page 8: Design by Contract

ОкорректностиПО

•Код сам по себе, не является корректным или некорректным!•Важна спецификация•«Задокументированный баг – это фича!»

Page 9: Design by Contract

Утверждениявконтрактах•Предусловия•Постусловия•Инвариант класса•Утверждения•Инвариант цикла (Eiffel specific)

Page 10: Design by Contract

Внедрение спецификациивкод

class Repository : IRepository{    public Customer GetCustomer(string id)    {        Contract.Requires(id != null);        Contract.Ensures( Contract.Result<Customer>() != null);    }}

Page 11: Design by Contract

Нарушенияутверждений•Нарушение предусловия – «баг» в

клиенте коде•Нарушение постусловия, инварианта

или утверждения – «баг» в сервисе

Page 12: Design by Contract

Инструменты DbC

•Утверждения•Статический анализатор•Документация (DRY)

Page 13: Design by Contract

– Контракты этообщее, понятие которое

покрываетмногие известныеООпринципы

Page 14: Design by Contract

ПринципзамещенияЛисков...если для каждого объекта o1 типа S существует объект o2 типа T такой, что для всех программ P, определенных в терминах T, поведение P не изменяется при замене o2 на o1, то S является подтипом (subtype) для T.

Sergey
Может добавить рисунок? P - программу, объекты o1 и o2?
Page 15: Design by Contract

ПринципзамещенияЛисков

Page 16: Design by Contract

Метод Add

• ICollection.Add• IList.Add•Может ли метод добавлять 2 элемента?•Или не добавлять ни одного?

Page 17: Design by Contract

Правиланаследования

•Наследник может•ослабевать предусловие• усиливать постусловие•Инварианты суммируются

Page 18: Design by Contract

Сильныеислабыеусловия•X > 0 (слабее)•X > 5 (сильнее, строже)

Page 19: Design by Contract

Предусловиеинаследование

Page 20: Design by Contract

Отношениемеждутипами

Page 21: Design by Contract

Ковариантностьпо типу возвращаемого

значения

Page 22: Design by Contract

Контравариантность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

Ковариантность 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

Ковариантностьисключений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

Принципсамурая

Page 26: Design by Contract

Мониторинг утвержденийво время

выполнения•Уровни утверждений•None•Requires•Ensures•Full•Assert on Contract Failures

Page 27: Design by Contract

Утвержденияивнешниеданные

Page 28: Design by Contract

Контракты vs Защитноепрограммирование

Проверка предусловий

(2 открытых метода)

Проверка при каждом обращении к полю (27 мест!)

Page 29: Design by Contract

Code Contracts

•Частичная поддержка в .NET 4.0•Устанавливается отдельно:•Статический анализатор•Rewriter• Генератор документации

Page 30: Design by Contract

Вернемсякметоду 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

Адаптация существующегокода

•Уже есть класс Guard?•Добавляем атрибут и получаем предусловие!

Page 32: Design by Contract

Code Contracts

•Contract.Requires•Contract.Ensures•Contract.Invariant•Contract.Assert/Assume

Page 33: Design by Contract

Альтернативная проверкапредусловий

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

Альтернативная проверкапредусловий

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

Ограничения DbC

•Аккуратнее со статическим анализатором!•Не переусердствуйте в формализации•Частичная поддержка Code Contracts в .NET Framework

Page 36: Design by Contract

ВажнейшиепринципыDbC• Разделение ответственности• Упрощение обязанностей•Обобщение существующих понятий•Формализация отношений

Page 37: Design by Contract

Дополнительныематериалы• Бертран Мейер, “Объектно-ориентированное конструирование

программных систем”• С. Тепляков, “Проектирование по контракту”, RSDN Magazine #1-

2010• Programming Stuff. “Альтернативная проверка предусловий в

Code Contracts”• Programming Stuff. “Принцип замещения Лисков и контракты”• Programming Stuff. “Принцип самурая”• Programming Stuff. “Как не надо писать код”• Александр Бындю. “Дополнение к LSP”

Page 38: Design by Contract

Спасибо за внимание

• Сергей Тепляков, Visual C# MVP• .NET Architect at Luxoft

[email protected]• http://sergeyteplyakov.blogspot.com/