Code Contracts ABC 16.04.2011

1,479 views
1,361 views

Published on

Published in: Technology
2 Comments
1 Like
Statistics
Notes
No Downloads
Views
Total views
1,479
On SlideShare
0
From Embeds
0
Number of Embeds
32
Actions
Shares
0
Downloads
11
Comments
2
Likes
1
Embeds 0
No embeds

No notes for slide

Code Contracts ABC 16.04.2011

  1. 1. Проектирование по контракту<br />DmytroMindra<br />RnD Tech Lead<br />LohikaLabs<br />Киев, 2011<br />
  2. 2. Дополнение к докладу<br />ВАЖНО:<br />Можно работать на Visual Studio 2010 Professional. Для этого ставятся Code ContractsStandard Edition. Будет доступно все, кроме статического анализа.<br />В Code Contracts Premium Edition доступен статический анализ контрактов.<br />
  3. 3. © Drake Emko & Jen Brodzik, 2001<br />
  4. 4. © Drake Emko & Jen Brodzik, 2001<br />
  5. 5. © Drake Emko & Jen Brodzik, 2001<br />
  6. 6. Northeast Blackout<br />Северо-восточное <br />отключение света<br />14 августа2003<br />12:15 p.m. Оператор компании MISO отключает систему <br /> прогнозирования проблем, чтобы подправить <br /> вручную данные и забывает ее включить в <br /> автоматическом режиме.<br />2:02 p.m. Отказала первая линия 345 кВ<br />2:14 p.m. Отказ системы оповещения (основной и резервной)<br />3:05 p.m. Отказ второй линии 345 кВ<br />3:17 p.m. Падение напряжения. Срабатывают контроллеры <br /> и перераспределяют нагрузку.<br />3:32 p.m. В результате перераспределения нагрузки <br /> выходит из строя еще одна линия 345 кВ. <br /> Начинается каскадный выход из строя <br /> перегруженных линий. Т.к. компании MISO и<br />FirstEnergy не предупредили соседей о проблемах.<br />
  7. 7. 4:13 p.m. Конец каскадных отключений. <br />256 электростанций отключены.<br />55 миллионов людей без электричества <br />более 24 часов.<br />
  8. 8. Ariane 5 (501)<br />4 июня 1996 года<br />
  9. 9. 37секунд полета<br />US$370-500миллионовубытка<br />US$ 7 миллиардовна разработку<br />Задержка миссии ЕКА на 4года<br />64-bit floating point  => 16-bit signed integer<br />Как же дублирование систем ?<br />Резервная система пала жертвой той же ошибки.<br />Главный модуль остался без данных.<br />И принял неверное решение.<br />
  10. 10. 56 запусков<br />2 неудачных<br />2 частично неудачных<br />52 удачных запуска<br />ЕКА запустили спутники при помощи Arian 5?<br />Нет. Использовался Союз Фрегат.<br />
  11. 11.
  12. 12. Ошибки в медицинском ПО<br />Therac-25 c 1985 по 1987 6 несчастных случаев по вине ПО.[15]<br />По ошибке программы MultidataSystemsInternational погибло 8 человек. 20 получили высокую дозу радиации. Физиотерапевты, ответственные за ручную проверку дозы, обвинены в убийстве. [15]<br />
  13. 13.
  14. 14. Так должно быть<br />
  15. 15. А так есть<br />
  16. 16. ОПАСНАЯ ТОРГОВЛЯ ФРУКТАМИ<br />
  17. 17.     public interface IFruit {}        public interface IFruitService    {        IFruit GetFruit();    }    <br />    public class Fruit:IFruit { }    public class FruitService : IFruitService {<br />        public IFruit GetFruit(){            return new Fruit();        }<br />    }<br />Абстракции<br />Реализации<br />
  18. 18.     public class FruitDealer    {        private readonly IFruitService _fruitService;        private double _dealerMoney;                public FruitDealer(IFruitService fruitService)        {            _fruitService = fruitService;        }        public IFruit SellFruit(double money)        {            _dealerMoney += money;            return _fruitService.GetFruit();        }    }<br />Частные <br />поля<br />Конструктор<br />money<=0 ?<br />Важный<br />метод<br />NullReferenceExceptional ?<br />FruitDealerdealer = new FruitDealer(null);<br />/* Some of code */<br />IFruitfruit = dealer.SellFruit(-10);<br />
  19. 19. public class FruitDealer    {        private readonly IFruitService _fruitService;        private double _dealerMoney;                public FruitDealer(IFruitService fruitService)<br />        {<br />            _fruitService = fruitService;        }        public IFruit SellFruit(double money)        {<br />           <br />  _dealerMoney += money;            return _fruitService.GetFruit();        }    }<br />// fruitService should not be null<br />if (fruitService==null)<br /> throw new ArgumentNullException("fruitService");<br />// money should be >0<br />if (money<=0)<br /> throw new ArgumentOutOfRangeException("money");<br />
  20. 20. Недостатки<br />Код с исключениями плохо подходит в качестве контрактов так как плохо читается.<br />Этот подход невозможно привязать к интерфейсам.<br />При перегрузке методов в наследниках придется заново прописывать проверки.<br />Проверками невозможно/сложно управлять.<br />
  21. 21. Проекированиепо контракту<br />
  22. 22. Проектирование по контракту<br />Не только хорошее слово<br />А также нужное дело<br />И зарегистрированная торговая марка<br />Design by Contract<br />
  23. 23. Design by ContractTM<br />Бертран Мейер<br />Автор проектирования по контракту и языка Eifel. Автор 11 книг<br />Включая“Object-Oriented Software Construction”<br />Первое издание: 1988<br />Второе издание: 1997<br />
  24. 24. Контракт – это …<br />метод проектирования программного обеспечения. Он предполагает, что проектировщик должен определить формальные, точные и верифицируемые спецификации интерфейсов для компонентов системы. При этом, кроме обычного определения абстрактных типов данных, также используются предусловия, постусловия и инварианты. Данные спецификации называются "контрактами" в соответствии с концептуальной метафорой условий и ответственностей в бизнес-контрактах. (wikipedia)<br />
  25. 25. Предусловия<br />Проверяют правильно соблюдены ли условия контракта клиентом. Все ли параметры переданы и правильные ли им присвоены значения.<br />GIGO (англ. GarbageIn, GarbageOut, «Мусор на входе — мусор на выходе») <br />
  26. 26. Постусловия<br />Проверяют возвращает ли поставщик именно то, что предписано контрактом. «Правильность» результата так сказать.<br />
  27. 27. Инварианты<br />Инварианты проверяют не был ли поврежден поставщик в процессе выполнения метода. Соответствует ли его состояние после вызова метода контракту. И соответственно готов ли он к дальнейшей работе.<br />
  28. 28. Пример на EIFEL<br />deposit (amount: INTEGER) is <br />require <br />non_negative: amount > 0 <br />do <br /> balance := balance + amount <br />ensure <br /> updated: balance = old balance + amount end<br />
  29. 29. С ЧЕГО НАЧАТЬ ?<br />
  30. 30. Нужна Visual Studio 2010 (Premium , Ultimate)<br />Декларативные контракты включеныв .NET 4.0 (System.Diagnostics.Contracts)<br />Для полноценной работы нужно установить инструменты (CodeContract Tools).<br />Инструменты включают в себя:<br />generate runtime checking from the contracts(ccrewrite)<br />do a static check that verifies contracts at compile-time (cccheck)<br />add contracts to the XML documentation files (ccdoc)<br />LOCATION: [Program Files]MicrosoftContractsBin<br />
  31. 31. Где наш диллер<br />
  32. 32. Наш первый контракт<br />public class FruitDealer<br />{<br />private readonlyIFruitService_fruitService;<br />private double _dealerMoney;<br /> public FruitDealer(IFruitServicefruitService)<br /> {<br />Contract.Requires(fruitService!=null);<br />_fruitService = fruitService;<br /> }<br /> public IFruitSellFruit(double money)<br />{<br />Contract.Requires(money > 0);<br />Contract.Ensures(Contract.Result<IFruit>()!=null);<br /> _dealerMoney += money;<br /> return _fruitService.GetFruit();<br /> }<br /> }<br />Контракт<br />Обязательстваклиента<br />Обязательства поставщика<br />
  33. 33. Проверка №1<br />FruitDealerdealer1 = new FruitDealer(null);<br />
  34. 34. Проверка №2<br />FruitDealerdealer2 = new FruitDealer(new FruitService());<br />IFruitfruit2 = dealer2.SellFruit(-10);<br />
  35. 35. После установки инструментов появится новая вкладка<br />
  36. 36. System.Diagnostics.Contracts<br />Contract<br />Attributes<br />ContractClassAttribute<br />ContractClassForAttribute<br />ContractInvariantMethodAttribute<br />ContractPublicPropertyNameAttribute<br />ContractReferenceAssemblyAttribute<br />ContractRuntimeIgnoredAttribute<br />ContractVerificationAttribute<br />PureAttribute ( is not enforced by analysis tools )<br />ContractFailedEventArgs<br />ContractFailureKind (enum)<br />
  37. 37. Основные методы<br />Pre-conditions: Requires<br />Post-conditions: Ensures<br />Invariants: Invariant<br />See also: EnsuresOnThrow<TException><br /> Requires<TException><br />
  38. 38. Давайте сравним<br />    public class Customer {        private int _ID;        public int ID        {            get            {                return _ID;            }            <br /> set            {               <br />  if (value <= 0) throw new ArgumentException();                <br /> _ID = value;            }        }}<br />public class Customer{    private int _ID;    public int ID    {        get        {            return _ID;        }        set         {<br />Contract.Requires(value > 0);             <br /> _ID = value;        }    }}<br />Было<br />Стало<br />
  39. 39. Первая демонстрация<br />
  40. 40. Что там внутри ?<br />
  41. 41. Processing collections<br />Integer range<br />ForAll(Int32, Int32, Predicate<Int32>)<br />Exists(Int32, Int32, Predicate<Int32>)<br />Collection<br />ForAll<T>(IEnumerable<T>, Predicate<T>)<br />Exists<T>(IEnumerable<T>, Predicate<T>)<br />
  42. 42. Демонстрация работы с коллекциями<br />
  43. 43. Проверка результатов<br />OldValue<T><br />Result<T><br />ValueAtReturn<T><br />
  44. 44. Демонстрация проверки результатов<br />
  45. 45. Другие методы<br />Assert – Проверка условия<br />Assume – Влияет на статическую проверку, добавляя утверждение в базу фактов статического анализатора. Влияет только на статический анализ. Во время выполнения трактуется как Assert. [3]<br />EndContractBlock - for legacy contracts<br />
  46. 46. Assert & Assume<br />public void Invoke() <br />{ <br />int x = CalculateSomeValues(); <br />// Tell the checker to verify whether<br />// x>0. <br />// (The checker might <br />// be unable to do it.) <br />Contract.Assert( x>0 ); <br />// Rest of the code <br />}<br />public void Invoke() { <br />int x = CalculateSomeValues(); <br />// Explicitly tell the checker that <br />//x>0 <br />Contract.Assume( x>0 );<br />// Rest of the code <br />}<br />
  47. 47. Наследование<br />Два правила[7]<br />При наследовании и перегрузке метода, а также при реализации интерфейса, контракты наследуются.<br />Нельзя добавить предусловия,но можно усилить постусловия и добавить инварианты. <br />E.g was require x>10<br />Added require x>100<br />Now x = 20 fulfills 1st require but violates 2nd;<br />
  48. 48. Демонстрация: наследование и ловушки<br />
  49. 49. Обработка ContractFailed<br />Contract.ContractFailed += <br />ContractContractFailed;<br />static void ContractContractFailed(<br /> object sender, ContractFailedEventArgs e) {  e.SetHandled(); // exception handledConsole.WriteLine(e.Message);}<br />
  50. 50. ДемонстрацияContractFailed<br />
  51. 51. custom contracts &custom rewriters methods<br />public static class RuntimeFailureMethods {  public static void Requires(bool cond, string userMsg, string condText) { }  public static void Ensures(bool cond, string userMsg, string condText) { }…<br />}<br />See user manual 7.7. (page 34) [12]<br />
  52. 52. Code snippets<br />crContract.Requires(...);<br />ce Contract.Ensures(...);<br />ci Contract.Invariant(...);<br />More in user manual 6.3. (page 26) [12]<br />
  53. 53. ВНЕДРЕНИЕ<br />
  54. 54. Code Contracts инструкция страница 18<br />Нужна валидацияя аргументов в релизном коде<br />нет<br />да<br />Допустимо использование contract tools<br />нет<br />да<br />Используем предусловия везде.<br />Включаем контракты только для дебага<br />Requires<Ex> на публичных методах<br />Requires везде<br />Runtime на всех билдах<br />Только предусловия и только на публичных методах.<br />If-throw на публичных методах<br />Помечаем их EndContractBlock<br />Используем Requires везде<br />Runtime checking только для отладочных сборок<br />
  55. 55. Как внедрять ?<br />Только в тех случаях, когда другие разработчики могут пользоваться поставляемыми вами библиотеками.<br />Только на публичных внешних методах.<br />Только предусловия.<br />Можно применять другие практики.<br />Это инструмент разработчика.<br />
  56. 56. Выводы и перспективы<br />CodeContracts активно развивается<br />В BCL активно используются CodeContracts<br />Статическая проверка<br />CodeContracts могут положительно повлиять на архитектуру<br />Дополнение к документации<br />Еще один хороший инструмент<br /> ( Не единственный, а один из)<br />
  57. 57. PEX<br />Path-based program exploration<br />
  58. 58. Демонстрация PEX<br />
  59. 59. СПАСИБО !<br />Вопросы ?<br />
  60. 60. Книги<br />Touch of Class: learning to program well with objects and contracts<br />Object-Oriented Software Construction<br />Object-Oriented Software Construction<br />Bertrand Meyer<br />1988,1997<br />
  61. 61. Ссылки<br />[1] Design by Contract - A Conversation with Bertrand Meyer, Part II by Bill Venners<br />http://www.artima.com/intv/contracts.html<br />[2] Defensive programming<br />http://en.wikipedia.org/wiki/Defensive_programming<br />[3] Dino Esposito, Code Contracts Preview: Preconditions<br />http://dotnetslackers.com/articles/net/Code-Contracts-Preview-Preconditions.aspx<br />[4] Dino Esposito, Code Contracts Preview: PostConditions<br />http://dotnetslackers.com/articles/net/Code-Contracts-Preview-PostConditions.aspx<br />[5] Dino Esposito, Code Contracts Preview: Invariants<br />http://dotnetslackers.com/articles/net/Code-Contracts-Preview-Invariants.aspx<br />[6] Dino Esposito, Code Contracts Preview: Assert & Assume<br />http://dotnetslackers.com/articles/net/Code-Contracts-Preview-Assert-Assume.aspx<br />[7] Jon Skeet, Code Contracts in C#<br />http://www.infoq.com/articles/code-contracts-csharp<br />[8] Design by Contract - Wikipedia<br />http://en.wikipedia.org/wiki/Design_by_contract<br />[9] Precondition - Wikipedia<br />http://en.wikipedia.org/wiki/Precondition<br />[10] Postcondition - Wikipedia<br />http://en.wikipedia.org/wiki/Postcondition<br />[11] Invariant - Wikipedia<br />http://en.wikipedia.org/wiki/Invariant_(computer_science)<br />[12] Code Contracts User Manual<br />http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf<br />[13] Code contracts and inheritance<br />http://stefanoricciardi.com/2009/07/17/code-contracts-and-inheritance/<br />[14] Assertions in Managed Code<br />http://msdn.microsoft.com/en-us/library/ttcc4x86.aspx<br />[15] History's Worst Software Bugs<br />http://www.wired.com/software/coolapps/news/2005/11/69355?currentPage=2<br />

×