SlideShare a Scribd company logo
SOLID
The most famous acronym in dev
План

OOA&D

Плохой OOD

Хороший OOD

SOLID

Выводы
OOA&D

OOA&D - объектно ориентированный
анализ и дизайн

OOA - объекты, отражающие
                          What?
функциональные требования

OOD - как эти объекты
                        How?
взаимодействуют
Почему важен
   хороший OOD?
Позволяет разрабатывать быстрее

Позволяет поддерживать высокое
качество на протяжении всего цикла
разработки

Упрощает понимание работы системы
Плохой дизайн
Плохой дизайн
Rigidity - закрепощённость

Fragility - хрупкость

Immobility - монолитность

Viscosity - вязкость

Complexity - неоправданная сложность

A lot of code smells - говнокод
Rigidity /
 закрепощённость
Система с трудом поддаётся
изменениям

Последствия даже простых изменений
непредсказуемы

Одно изменение влечёт за собой каскад
изменений в куче модулей

Тяжело оценить затраты на изменение
Fragility / хрупкость

Внесение изменений ломает систему в
совершенно непредсказуемых местах




В процессе исправления этих ошибок
появляются новые
Immobility /
    монолитность
Выделение компонентов системы,
которые могли бы повторно
использоваться, приводит к большим
рискам

Проще написать заново, чем что-то
переиспользовать
Viscosity / вязкость

Хак сделать проще, чем написать так,
как задумано дизайном

Расширение дизайна проходит
болезненно и тяжело

Вероятность ошибки при следовании
дизайну очень высока
Complexity /
      сложность

Вангующие разработчики, пытающиеся
предсказать будущие требования

Как итог — много лишнего кода/дизайна
«на будущее»
Code smells / говнокод

 Копипаст

 God-objects

 Много параметров в методах

 Методы на 500 строк
Хороший дизайн

Гибкость

Прочность

Подвижность

Простота

Прозрачность
SOLID is all for good
       design
SRP - single responsibility

OCP - open/closed

LSP - Liskov substitution

ISP - interface segregation

DIP - dependency inversion
SRP / Единственность
  ответственности
SRP / Единственность
  ответственности

 Компонент должен иметь только одну
 область ответственности

 Компонент должен иметь только одну
 причину для изменения
SRP / Единственность
  ответственности
   interface IModem
   {
      void Dial(string number);
      void Send(byte[] data);
      byte[] Receive();
   }
SRP / Единственность
  ответственности

 Active Record

 Manager*, *Processor, *Handler

 God-objects
OCP / открытость-
   закрытость
OCP / открытость-
   закрытость
Компоненты должны быть открыты для
расширения, но закрыты от изменений

Поведение компонента можно
расширить без изменения его
внутренней реализации

Use abstractions, Luke!
OCP / открытость-
       закрытость
void Draw(Shape[] shapes)
{
    foreach (var shape in shapes)
    {
        Type type = shape.GetType();
        if (type == typeof(Square))
             DrawSquare((Square)shape);
             else if (type == typeof(Circle))
                 DrawCircle((Circle)shape);
                 }
    }
}
OCP / открытость-
   закрытость
Часто изменяющиеся вещи держите подальше
от тех, которые изменяются редко

Если они зависят друг от друга, часто
изменяющиеся компоненты должны зависеть от
редко изменяющихся. Не наоборот!

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

В места, где используются подтипы, можно
подставить базовый тип без неожиданных
изменений в поведении
LSP / Принцип
  замещения Лисков
public class DoubleList<T> : IList<T>
{
    private readonly IList<T> _innerList = new
List<T>();
  
    public void Add(T item)
    {
        innerList.Add(item);
        innerList.Add(item);
    }
}
LSP / Принцип
замещения Лисков

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

Наследуемый объект может изменить
родительское пред-условие на такое же
или более слабое, а пост условие на
такое же или более сильное
LSP / Принцип
замещения Лисков

IList.Add(object) Пред-условие: object !=
null, пост условие - Count = Count + 1

DoubleList.Add(object) Пред-условие:
object != null, пост условие - Count =
Count + 2
ISP / разделение
  интерфейсов
ISP / разделение
   интерфейсов
Большие классы бывают

Клиенту не всегда нужны все методы
класса

Клиент не должен зависеть от того, что
он не использует
DIP / инверсия
    зависимостей
Модули верхнего уровня не должны
зависеть от модулей нижнего уровня.
Оба должны зависеть от абстракций.

Абстракция не должна зависеть от
деталей реализации, детали реализации
должны зависеть от абстракций
DIP / инверсия
         зависимостей
public class Reporter
{
     public void SendReports()
     {
        var reportBuilder = new ReportBuilder();
        var report = reportBuilder.CreateReport();
        var reportSender = new EmailReportSender();
        reportSender.Send(report);
    }
}
DIP / инверсия
            зависимостей
public class Reporter
{
     private readonly IReportBuilder _builder;
     private readonly IReportSender _sender;

      public Reporter(IReportBuilder builder,
                      IReportSender sender)
      {
         _builder = builder;
        _sender = sender;
      }
     public void SendReports()
     {
        var report = _builder.CreateReport();
        _sender.Send(report);
    }
}
DIP / инверсия
 зависимостей
DIP / инверсия
 зависимостей
DIP / инверсия
    зависимостей
Стремитесь нигде не зависеть от
конкретных реализаций, зависьте от
абстракций

Стремитесь выделять абстракции

Dependency Injection, особенно в
конструкторах

IoC контейнеры
Выводы
Хороший дизайн — это непросто, но достижимо

Вовремя избавляйтесь от плохих запахов, закрывайте
технические долги

Хороший дизайн почти всегда подразумевает слабое
связывание

Читайте книги и старайтесь применять знания на практике

Не бросайтесь сразу менять архитектуру вашего проекта,
применяйте принципы только тогда, когда это нужно

More Related Content

Similar to SOLID

SOLID
SOLIDSOLID
SOLID
DelphiCon
 
SOLID
SOLIDSOLID
SOLIDарность: Тестирование как разработка
SOLIDарность: Тестирование как разработкаSOLIDарность: Тестирование как разработка
SOLIDарность: Тестирование как разработка
SQALab
 
Проблемы точечной застройки в больших городах или зачем нужен Dagger
Проблемы точечной застройки в больших городах или зачем нужен DaggerПроблемы точечной застройки в больших городах или зачем нужен Dagger
Проблемы точечной застройки в больших городах или зачем нужен Dagger
Valeriya Atamanova
 
ук 03.001.02 2011
ук 03.001.02 2011ук 03.001.02 2011
ук 03.001.02 2011etyumentcev
 
разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)
Alexander Gornik
 
BE SOLID
BE SOLIDBE SOLID
BE SOLID
Avivi Academy
 
Как пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftКак пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на Swift
Anton Loginov
 
Секрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдноСекрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдно
CUSTIS
 
Yuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practicesYuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practicesbeloslab
 
Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.
EatDog
 
Software Design Patterns
Software Design PatternsSoftware Design Patterns
Software Design Patterns
Eugene Merkoulov
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
Alexander Granin
 
Как жить в согласии с SOLID?
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?
etyumentcev
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Yauheni Akhotnikau
 
S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014
S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014
S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014
Python Meetup
 
Принципы SOLID
Принципы SOLIDПринципы SOLID
Принципы SOLID
Unguryan Vitaliy
 
Gang of four review.Structural patterns
Gang of four review.Structural patternsGang of four review.Structural patterns
Gang of four review.Structural patterns
Mykyta Hopkalo
 

Similar to SOLID (20)

SOLID
SOLIDSOLID
SOLID
 
SOLID
SOLIDSOLID
SOLID
 
SOLIDарность: Тестирование как разработка
SOLIDарность: Тестирование как разработкаSOLIDарность: Тестирование как разработка
SOLIDарность: Тестирование как разработка
 
Проблемы точечной застройки в больших городах или зачем нужен Dagger
Проблемы точечной застройки в больших городах или зачем нужен DaggerПроблемы точечной застройки в больших городах или зачем нужен Dagger
Проблемы точечной застройки в больших городах или зачем нужен Dagger
 
ук 03.001.02 2011
ук 03.001.02 2011ук 03.001.02 2011
ук 03.001.02 2011
 
разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)
 
BE SOLID
BE SOLIDBE SOLID
BE SOLID
 
Как пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftКак пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на Swift
 
Секрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдноСекрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдно
 
Yuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practicesYuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practices
 
Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.
 
Software Design Patterns
Software Design PatternsSoftware Design Patterns
Software Design Patterns
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
 
Как жить в согласии с SOLID?
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
IoC & Dependency Injection
IoC & Dependency InjectionIoC & Dependency Injection
IoC & Dependency Injection
 
S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014
S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014
S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014
 
Принципы SOLID
Принципы SOLIDПринципы SOLID
Принципы SOLID
 
Tdd php
Tdd phpTdd php
Tdd php
 
Gang of four review.Structural patterns
Gang of four review.Structural patternsGang of four review.Structural patterns
Gang of four review.Structural patterns
 

SOLID

  • 1. SOLID The most famous acronym in dev
  • 3. OOA&D OOA&D - объектно ориентированный анализ и дизайн OOA - объекты, отражающие What? функциональные требования OOD - как эти объекты How? взаимодействуют
  • 4. Почему важен хороший OOD? Позволяет разрабатывать быстрее Позволяет поддерживать высокое качество на протяжении всего цикла разработки Упрощает понимание работы системы
  • 6. Плохой дизайн Rigidity - закрепощённость Fragility - хрупкость Immobility - монолитность Viscosity - вязкость Complexity - неоправданная сложность A lot of code smells - говнокод
  • 7. Rigidity / закрепощённость Система с трудом поддаётся изменениям Последствия даже простых изменений непредсказуемы Одно изменение влечёт за собой каскад изменений в куче модулей Тяжело оценить затраты на изменение
  • 8. Fragility / хрупкость Внесение изменений ломает систему в совершенно непредсказуемых местах В процессе исправления этих ошибок появляются новые
  • 9. Immobility / монолитность Выделение компонентов системы, которые могли бы повторно использоваться, приводит к большим рискам Проще написать заново, чем что-то переиспользовать
  • 10. Viscosity / вязкость Хак сделать проще, чем написать так, как задумано дизайном Расширение дизайна проходит болезненно и тяжело Вероятность ошибки при следовании дизайну очень высока
  • 11. Complexity / сложность Вангующие разработчики, пытающиеся предсказать будущие требования Как итог — много лишнего кода/дизайна «на будущее»
  • 12. Code smells / говнокод Копипаст God-objects Много параметров в методах Методы на 500 строк
  • 14.
  • 15. SOLID is all for good design SRP - single responsibility OCP - open/closed LSP - Liskov substitution ISP - interface segregation DIP - dependency inversion
  • 16. SRP / Единственность ответственности
  • 17. SRP / Единственность ответственности Компонент должен иметь только одну область ответственности Компонент должен иметь только одну причину для изменения
  • 18. SRP / Единственность ответственности interface IModem { void Dial(string number); void Send(byte[] data); byte[] Receive(); }
  • 19. SRP / Единственность ответственности Active Record Manager*, *Processor, *Handler God-objects
  • 20. OCP / открытость- закрытость
  • 21. OCP / открытость- закрытость Компоненты должны быть открыты для расширения, но закрыты от изменений Поведение компонента можно расширить без изменения его внутренней реализации Use abstractions, Luke!
  • 22. OCP / открытость- закрытость void Draw(Shape[] shapes) { foreach (var shape in shapes) { Type type = shape.GetType(); if (type == typeof(Square)) DrawSquare((Square)shape); else if (type == typeof(Circle)) DrawCircle((Circle)shape); } } }
  • 23. OCP / открытость- закрытость Часто изменяющиеся вещи держите подальше от тех, которые изменяются редко Если они зависят друг от друга, часто изменяющиеся компоненты должны зависеть от редко изменяющихся. Не наоборот! Предпочитайте композицию наследованию
  • 25. LSP / Принцип замещения Лисков Eсли для каждого объекта o1 типа S существует объект o2 типа T, который для всех программ P определен в терминах T, то поведение P не изменится, если o1 заменить на o2 при условии, что S является подтипом T.
  • 26. LSP / Принцип замещения Лисков Подтипы должны быть полностью заменяемыми базовыми типами в местах, где они используются В места, где используются подтипы, можно подставить базовый тип без неожиданных изменений в поведении
  • 27. LSP / Принцип замещения Лисков public class DoubleList<T> : IList<T> {     private readonly IList<T> _innerList = new List<T>();        public void Add(T item)     {         innerList.Add(item);         innerList.Add(item);     } }
  • 28. LSP / Принцип замещения Лисков Проектирование по контракту Наследуемый объект может изменить родительское пред-условие на такое же или более слабое, а пост условие на такое же или более сильное
  • 29. LSP / Принцип замещения Лисков IList.Add(object) Пред-условие: object != null, пост условие - Count = Count + 1 DoubleList.Add(object) Пред-условие: object != null, пост условие - Count = Count + 2
  • 30. ISP / разделение интерфейсов
  • 31. ISP / разделение интерфейсов Большие классы бывают Клиенту не всегда нужны все методы класса Клиент не должен зависеть от того, что он не использует
  • 32. DIP / инверсия зависимостей Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций. Абстракция не должна зависеть от деталей реализации, детали реализации должны зависеть от абстракций
  • 33. DIP / инверсия зависимостей public class Reporter {      public void SendReports()      {         var reportBuilder = new ReportBuilder();         var report = reportBuilder.CreateReport();         var reportSender = new EmailReportSender();         reportSender.Send(report);     } }
  • 34. DIP / инверсия зависимостей public class Reporter { private readonly IReportBuilder _builder; private readonly IReportSender _sender; public Reporter(IReportBuilder builder, IReportSender sender) { _builder = builder; _sender = sender; }      public void SendReports()      {         var report = _builder.CreateReport();         _sender.Send(report);     } }
  • 35. DIP / инверсия зависимостей
  • 36. DIP / инверсия зависимостей
  • 37. DIP / инверсия зависимостей Стремитесь нигде не зависеть от конкретных реализаций, зависьте от абстракций Стремитесь выделять абстракции Dependency Injection, особенно в конструкторах IoC контейнеры
  • 38. Выводы Хороший дизайн — это непросто, но достижимо Вовремя избавляйтесь от плохих запахов, закрывайте технические долги Хороший дизайн почти всегда подразумевает слабое связывание Читайте книги и старайтесь применять знания на практике Не бросайтесь сразу менять архитектуру вашего проекта, применяйте принципы только тогда, когда это нужно