Your SlideShare is downloading. ×
0
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Принципы объектно-ориентированного дизайна

6,290

Published on

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

No Downloads
Views
Total Views
6,290
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
0
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Рефакторинг и объектно-ориентированный дизайн
    Ingate Development
    2011
  • 2. Обращаться с языком кое-как — значит и мыслить кое-как: приблизительно, неточно, неверно.
    А. Н. Толстой.
    Код программы чаще читается, чем пишется.
    Народная мудрость.
    Цель: узнать, что такое правильный объектно-ориентированный дизайн программного обеспечения и какими способами его можно достигать.
    Ingate Development 2011
  • 3. О чем поговорим?
    • Обсудим, что такое правильный дизайн и как его добиться.
    • 4. Ответ на вопрос «что» дают принципы объектно-ориентированного дизайна и паттерны.
    • 5. Ответ на вопрос «как» дают техники рефакторинга.
    • 6. Будем в первую очередь разбираться в причинах того или иного варианта определения объектов и их взаимодействия.
    • 7. Поговорим о том, что идеального дизайна не существует и каждому из вас предстоит нелегкая задача поиска баланса между нарушениями разных принципов.
    Ingate Development 2011
  • 8. О чем не будем говорить?
    • Не будем разбирать конкретные паттерны объектно-ориентированного проектирования
    • 9. Не будем перечислять конкретные техники рефакторинга
    • 10. Хотя и паттерны и рефакторинг будем часто использовать в примерах.
    • 11. Не будем разбирать принципы объектно-ориентированного подхода.
    • 12. Не будем анализировать плюсы и минусы объектно-ориентированного подхода. Будем считать, что раз вы сюда пришли, то выбор вы для себя уже сделали.
    Ingate Development 2011
  • 13. ОО дизайн
    SOLID – этоаббревиатура пяти основных принципов дизайна в объектно-ориентированном проектировании. В дополнение к этому, рассмотрим еще шестой принцип, который не входит в эту аббревиатуру.
    Ingate Development 2011
  • 14. Рефакторинг
    Рефакторинг (англ. refactoring) — процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы.
    В основе рефакторинга лежит последовательность небольших эквивалентных (то есть сохраняющих поведение) преобразований.
    Поскольку каждое преобразование маленькое, программисту легче проследить за его правильностью, и в то же время вся последовательность может привести к существенной перестройке программы и улучшению её согласованности и четкости.
    Wikipedia
    Ingate Development 2011
  • 15. Single Responsibility Principle
    Принцип единственной обязанности
    Ingate Development 2011
  • 16. Single Responsibility Principle
    В объектно-ориентированном программировании, принцип единственной обязанности обозначает, что каждый объект должен иметь одну обязанность и эта обязанность должна быть полностью инкапсулирована в класс.
    Wikipedia
    Не должно существовать более одного мотива для изменения класса.
    Роберт Мартин
    Ingate Development 2011
  • 17. Single Responsibility Principle
    Ingate Development 2011
  • 18. Single Responsibility Principle
    Связность (cohesion):насколько сильно связаны и сонаправлены различные обязанности модуля
    Связанность (coupling):степень, в которой программный модуль зависит от других модулей
    Стремитесь к слабой связанности, но к сильной связности модулей
    Ingate Development 2011
  • 19. Single Responsibility Principle
    • Изменения в требованиях обычно влекут за собой изменение обязанностей
    • 20. Чем больше обязанностей у класса – тем больше вероятность его изменения
    • 21. Несколько обязанностей в пределах одного класса делают эти обязанности взаимозависимыми
    • 22. Чем больше классов затронет изменение, тем больше ошибок при этом наделают
    Ingate Development 2011
  • 23. Single Responsibility Principle
    Пример нарушения принципа
    Ingate Development 2011
  • 24. Single Responsibility Principle
    Описание проблемы
    • Оплата наличными не требует операций с кредитками
    • 25. Операции в розничной системе продаж не требуют резервирования товара на складе
    • 26. Операции на сайте не требуют отчисления бонусов торговому менеджеру
    • 27. При этом любые изменения в систему процессинга платежей, систему резервирования товаров или начисления бонусов затрагивает Order, а соответственно и оба модуля Web и SaleSystem
    Ingate Development 2011
  • 28. Single Responsibility Principle
    Рефакторинг
    Ingate Development 2011
  • 29. Open/Closed Principle
    Принцип открытости/закрытости
    Ingate Development 2011
  • 30. Open/Closed Principle
    Сущности в программе (классы, модули, функции и т.п.) должны быть открыты для расширения, но закрыты для изменения.
    Wikipedia
    Ingate Development 2011
  • 31. Open/Closed Principle
    Ingate Development 2011
  • 32. Open/Closed Principle
    Открыты для расширения
    Новая функциональность может быть добавлена в будущем
    Закрыты для изменения
    Изменения в исходниках или бинарных сборках не требуются для добавления функциональности
    Принцип впервые описан Бертраном Мейером в 1988 г.
    Ingate Development 2011
  • 33. Open/Closed Principle
    Пример нарушения принципа
    Ingate Development 2011
  • 34. Open/Closed Principle
    Описание проблемы
    • Добавление новых правил каждый раз требует изменения калькулятора
    • 35. Каждое изменение может наплодить багов и требует повторного тестирования
    • 36. Добавление новых классов в меньшей степени чревато проблемами:
    • 37. Нет кода, который зависит от новых классов (пока)
    • 38. Новые классы не имеют исторической связанности, которая затрудняет их проектирование и тестирование
    Ingate Development 2011
  • 39. Open/Closed Principle
    Три подхода к достижению OCP
    • Использование параметров
    • 40. Дайте клиентам возможность контролировать поведение через дополнительные параметры
    • 41. В сочетании с делегатами/лямбда-выражениями можно добиться очень хорошего результата
    • 42. Использование наследования
    • 43. Потомки определяют (доопределяют) поведение базового класса / интерфейса
    • 44. Использование паттерна «Стратегия»
    • 45. Клиентский код зависит от абстракции
    • 46. Используется модель «plug in», которая позволяет переопределять поведение, заменив абстракцию
    Ingate Development 2011
  • 47. Open/Closed Principle
    Рефакторинг
    Ingate Development 2011
  • 48. Open/Closed Principle
    Понимание приходит с опытом
    • Если ваш собственный опыт в предметной области подсказывает вам, что определенные изменения будут повторяться – примените OCP сразу при проектировании
    • 49. Если модуль изменяется в первый раз – нарушьте принцип и просто измените реализацию
    • 50. Если модуль изменяется повторно – примените рефакторинг для достижения OCP
    • 51. Бесплатный сыр бывает только в мышеловке:OCP всегда усложняет дизайн
    • 52. И помните:нет такого дизайна, который бы был закрыт от всех изменений
    Ingate Development 2011
  • 53. Liskov substitution principle
    Принцип подстановки Лисковой
    Ingate Development 2011
  • 54. Liskov substitution principle
    Функции, которые используют ссылки на базовые классы, должны иметь возможность использовать объекты производных классов, не зная об этом.
    Роберт Мартин
    Назван так в честь Барбары Лисковой, которая описала этот принцип впервые в 1988 г.
    Ingate Development 2011
  • 55. Liskov substitution principle
    Ingate Development 2011
  • 56. Liskov substitution principle
    Потомки (дочерние классы) не должны:
    • убирать поведение предков
    • 57. нарушать контрактные обязательства предков
    И вообще код при использовании потомков не должен знать, что он оперирует не предком, а чем-то еще.
    Ingate Development 2011
  • 58. Liskov substitution principle
    • Обычнопод наследованием понимают отношение«ISA»
    • 59. Strawberry IS A berry
    • 60. Клубника – это ягода
    • 61. С точки зрения принципа подстановки Лисковой правильнее говорить об отношении«IS SUBSTITUTABLE FOR»
    • 62. Strawberry IS SUBSTITUTABLE FOR berry
    • 63. Клубника может быть использована как ягода
    • 64. И тогда не будет неожиданностей…
    • 65. Волчья ягода – это ягода
    • 66. Волчья ягода может быть использована как ягода
    Ingate Development 2011
  • 67. Liskov substitution principle
    Типичное нарушение принципа
    abstractclassBase {
    publicabstractvoid Method1();
    publicabstractvoid Method2();
    }
    classDerived : Base {
    publicoverridevoid Method1() {
    thrownewNotImplementedException();
    }
     
    publicoverridevoid Method2() {
    // do something
    }
    }
     
    Ingate Development 2011
  • 68. Liskov substitution principle
    Типичное нарушение принципа
    publicvoidPrint(Employeeperson) {
    if(person isProgrammer) {
    _printer.PrintProgrammer(person);
    } elseif (person isManager) {
    _printer.PrintManager(person);
    }

    Ingate Development 2011
  • 69. Liskov substitution principle
    Пример нарушения принципа
    Ingate Development 2011
  • 70. Liskov substitution principle
    Описание проблемы
    • Клиентский код знает слишком много об устройстве используемого класса
    • 71. Доработки в коде сводятся к добавлению if-then или switch конструкций, что в свою очередь ведет к кошмару при поддержке данного кода
    • 72. Налицо нарушение принципа OCP
    Ingate Development 2011
  • 73. Liskov substitution principle
    Рефакторинг
    Ingate Development 2011
  • 74. Interface segregation principle
    Принцип изолированности интерфейса
    Ingate Development 2011
  • 75. Interface segregation principle
    Клиент не должен вынужденно зависеть от элементов интерфейса, которые он не использует.
    Роберт Мартин
    Смысл: предпочитайте маленькие, простые интерфейсы «жирным».
    Ingate Development 2011
  • 76. Interface segregation principle
    Ingate Development 2011
  • 77. Interface segregation principle
    Под интерфейсом здесь нужно понимать:
    • Интерфейс, описанный ключевым словом interfacepublicinterfaceIDoSomething{}
    • 78. Публичный интерфейс классаpublicclassSomeClass{}
    То есть то, что клиент видит и может использовать.
    Ingate Development 2011
  • 79. Interface segregation principle
    Пример нарушения принципа
    Ingate Development 2011
  • 80. Interface segregation principle
    Типичное нарушение принципа
    publicoverridevoidSomeMethod() {
    thrownewNotImplementedException();
    }
    Что само по себе является нарушением LSP
    Ingate Development 2011
  • 81. Interface segregation principle
    Когда нужно применять рефакторинг?
    • Нет неудобства – нет проблемы
    • 82. Если нет проблемы, то незачем и рефакторить
    • 83. Если ваш код зависит от «жирного» интерфейса и к нему есть доступ
    • 84. Создайте нужный маленький интерфейс
    • 85. Свяжите его с «жирным»
    • 86. Используйте новый интерфейс
    • 87. Если ваш код зависит от «жирного» интерфейса и к нему нет доступа
    • 88. Создайте нужный маленький интерфейс
    • 89. Реализуйте нужные методы используя промежуточный класс, реализующий «жирный» интерфейс (паттерн Adapter)
    Ingate Development 2011
  • 90. Interface segregation principle
    Рефакторинг
    Ingate Development 2011
  • 91. Dependency inversion principle
    Принцип инверсии зависимости
    Ingate Development 2011
  • 92. Dependency inversion principle
    Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций.
    Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
    Роберт Мартин
    Ingate Development 2011
  • 93. Dependency inversion principle
    Ingate Development 2011
  • 94. Dependency inversion principle
    Код обычно зависит от:
    • Framework
    • 95. Сторонние библиотеки
    • 96. База данных
    • 97. Файловая система
    • 98. Email
    • 99. Web services
    • 100. Системные ресурсы (часы, например)
    • 101. Конфигурация
    • 102. Ключевое слово new
    • 103. Статические методы
    • 104. Thread.Sleep()
    • 105. Random
    Ingate Development 2011
  • 106. Dependency inversion principle
    Традиционный подход
    • Модули более высокого уровня вызывают модули низшего уровня
    • 107. Пользовательский интерфейс зависит от
    • 108. Бизнес логики, которая зависит от
    • 109. Инфраструктурных классов
    • 110. Утилит / хелперов
    • 111. Обертки доступа к данным (DAO)
    • 112. Статические методы используются везде, потому что это удобно
    • 113. Создание объектов разбросано по всем модулям
    • 114. Типичное нарушение принципа SRP
    Ingate Development 2011
  • 115. Dependency inversion principle
    • Если конструктор требует определения всех зависимостей класса, то говорят о том, что класс имеет явныезависимости
    • 116. Если же этого нет, то класс имеет скрытые зависимости
    publicclassHelloWorldHidden {
    publicstring Hello(string name) {
    if (DateTime.Now.Hour < 12) {
    return"Good morning, " + name;
    }
    if (DateTime.Now.Hour < 18) {
    return"Good afternoon, " + name;
    }
    return"Good evening, " + name;
    }
    }
    Ingate Development 2011
  • 117. Dependency inversion principle
    Подход DIP
    • Классы должны явно указывать то, что они используют
    publicclassHelloWorldExplicit {
    privatereadonlyDateTime _timeOfGreeting;
    publicHelloWorldExplicit(DateTimetimeOfGreeting) {
    _timeOfGreeting = timeOfGreeting;
    }
    publicstring Hello(string name) {
    if (_timeOfGreeting.Hour < 12) {
    return"Good morning, " + name;
    }
    if (_timeOfGreeting.Hour < 18) {
    return"Good afternoon, " + name;
    }
    return"Good evening, " + name;
    }
    }
    Ingate Development 2011
  • 118. Dependency inversion principle
    Пример нарушения принципа
    Ingate Development 2011
  • 119. Dependency inversion principle
    Описание проблемы
    • OnlineOrderимеет скрытые зависимости:
    • 120. MailMessage
    • 121. SmtpClient
    • 122. InventorySystem
    • 123. PaymentGateway
    • 124. В результате
    • 125. Высокая связанность (coupling)
    • 126. Трудности с изменением поведения(нарушение принципа OCP)
    • 127. Класс сложно тестировать
    Ingate Development 2011
  • 128. Dependency inversion principle
    Внедрение зависимости
    • Данная техника означает, что вызывающий код может внедрить поведение в объект
    • 129. Три основные техники
    • 130. Внедрение через свойства
    • 131. Внедрение через конструктор
    • 132. Внедрение через параметры метода
    • 133. Есть и другие техники, конечно
    Ingate Development 2011
  • 134. Dependency inversion principle
    Внедрение через свойства
    • Плюсы
    • 135. Поведение может быть заменено в любой момент жизни объекта
    • 136. Поведение может быть настроено многими способами - очень гибкая методика
    • 137. Минусы
    • 138. Объекты могут быть в невалидном состоянии в промежуток времени между созданием и определением всех зависимостей через setter’ы
    • 139. Не всегда интуитивно понятно поведение
    Ingate Development 2011
  • 140. Dependency inversion principle
    Внедрение через конструктор
    • Плюсы
    • 141. Классы явно указывают клиентам, от чего они зависят
    • 142. Классы всегда находятся в валидном состоянии
    • 143. Минусы
    • 144. У конструкторов может быть слишком много параметров
    • 145. Иногда (при сериализации, например)требуется конструктор по умолчанию
    • 146. Некоторые методы могут не использовать все зависимости, описанные конструктором
    Ingate Development 2011
  • 147. Dependency inversion principle
    Внедрение через параметры
    • Плюсы
    • 148. Наиболее полное разделение поведения между методами
    • 149. Очень гибкие возможности
    • 150. Не требуется изменений всего класса
    • 151. Минусы
    • 152. Меняет сигнатуру методов
    • 153. Количество параметров может быть неприлично большим
    • 154. Если только один метод имеет зависимость, то используйте эту технику. Иначе – внедрение через конструктор
    Ingate Development 2011
  • 155. Dependency inversion principle
    Рефакторинг
    Ingate Development 2011
  • 156. Dependency inversion principle
    Типичные нарушения принципа
    foreach (var item incart.Items) {
    varinventorySystem = new InventorySystem();
    inventorySystem.Reserve(item);
    }
    var message = new MailMessage {
    Subject = "Заказ принят в " + DateTime.Now
    }; 
    Ingate Development 2011
  • 157. Dependency inversion principle
    Где же создавать объекты?
    • Конструктор по умолчанию
    • 158. Можно создавать все необходимые зависимости в конструкторе по умолчанию
    • 159. При этом будут созданы те реализации, которые должны чаще всего использоваться в приложении
    • 160. Такой вариант использования принципа называется«DIP для бедняков» (Poor man’s DIP)
    • 161. ФукнцияMain
    • 162. Можно создавать все, что вам нужно при старте программы
    • 163. IoC Container
    • 164. Можно использовать специализированную библиотеку
    Ingate Development 2011
  • 165. Dependency inversion principle
    Microsoft Unity
    Пример кода:
    IUnityContainermyContainer = newUnityContainer();
    myContainer.RegisterType<IMyService, CustomerService>();
    IMyServicemyServiceInstance = myContainer.Resolve<IMyService>();
    Ingate Development 2011
  • 166. Dependency inversion principle
    Традиционная архитектура приложения
    Ingate Development 2011
  • 167. Dependency inversion principle
    Подход DIP
    Ingate Development 2011
  • 168. Don’t repeat yourselfor Duplicate is evil
    Не повторяйся илиДублирование - зло
    Ingate Development 2011
  • 169. Don’t repeat yourself
    Каждое отдельное понятие должно иметь единственное, однозначное отражение в системе.
    Энди Хунт
    Логические повторы говорят о необходимости абстракции. Повторы в работе говорят о необходимости автоматизации.
    97 вещей, которые должен знать любой программист.
    Ingate Development 2011
  • 170. Don’t repeat yourself
    Ingate Development 2011
  • 171. Don’t repeat yourself
    Пример нарушения принципа
    Ingate Development 2011
  • 172. Don’t repeat yourself
    Что является дублированием?
    • Магические константы
    • 173. Дублирующаяся логика в разных частях кода
    • 174. Повторяющаяся if-then логика
    • 175. Однотипные операции
    • 176. Повторяющиеся вычисления во время выполнения
    Ingate Development 2011
  • 177. Don’t repeat yourself
    Рефакторинг
    Ingate Development 2011
  • 178. Don’t repeat yourself
    Повторения в процессе работы
    • Тестирование вручную – муторно и неэффективно
    • 179. Сборка вручную – это муторно и неэффективно
    • 180. Публикация вручную – это муторно и неэффективно
    • 181. Если вы поняли суть этого принципа, то у вас должно возникнуть желание написатьstring.Format("{0} вручную – это муторно и неэффективно", action);
    Ingate Development 2011
  • 182. На этом все 
    Почитать еще что-нибудь: dev.ingate.ru
    Задать мне вопрос: sergey.shebanin@ingate.ru

×