Как писать красивый код или
           основы S.O.L.I.D.




Пинин Денис
dpinin@codereign.net
Что такое S.O.L.I.D.?

S - Single Responsibility Principle (SRP)
                   (принцип единой ответственности)

O - Open/Closed Principle (OCP)
                   (принцип «открыто/закрыто»)


L - Liskov Substitution Principle (LSP)
                   (принцип замещения Лискоy)

I - Interface Segregation Principle (ISP)
                   (принцип разделения интерфейса)

D - Dependency Inversion Principle (DIP)
                   (принцип инверсии зависимостей)
Зачем соблюдать принципы S.O.L.I.D.?

• Помогают построить архитектуру
  приложения, которое со временем будет проще
  (дешевле) поддерживать и развивать.

• Помогаю писать повторно используемый код.




    Принципы !=
     Правила
Принцип единой ответственности (SRP)
 Формулировка: не должно быть больше одной причины для
                    изменения класса




    Почему?

              Потому что это ведет к хрупкости дизайна (пишем
                 один «функционал» - отваливается другой)
А может не надо?




Неееет….
Самый главный нарушительSRP – God Object:


      Как писать красивый код или
           основы S.O.L.I.D.




Пинин Денис
dpinin@codereign.net
Нарушитель побежден!
Принцип открытости/закрытости
                (OCP)
          Формулировка: программные сущности
(классы, модули, функции и т.д.) должны быть открыты для
          расширения, но закрыты для изменения




   Почему?

              Потому что позволяет быстро и безболезненно
                реагировать на изменения бизнес-логики
Чем плох этот код?
                      Заказчик: Лог продаж в файлах!?
                      Это же отстой! Изменение
                      требований: лог надо хранить в БД.




       Разработчик:
       Нет проблем!
Нарушаем принцип OCP!
А так лучше?
Принцип замещения Лисков (OCP)
   Формулировка №1: если для каждого объекта
  o1 типа S существует объект o2 типа T, который
  для всех программ P определен в терминах T, то
   поведение P не изменится, если o1 заменить на
    o2 при условии, что S является подтипом T.

                 (ничего не понятно)

Формулировка №2: подтипы должны быть заменяемы базовыми типами.



       Почему?

                    Потому что клиентский код начинает считать
                   производный класс разновидностью базового, и
                 возможно появление кода, явно использующего этот
                                      факт
Ошибочное наследование




Попробуем протестировать
Прямоугольник или квадрат?
Принцип разделения интерфейса (ISP)
     Формулировка: клиенты не должны зависеть от
         методов, которые они не используют




                  Потому что если мы определим большой
   Почему?     универсальный интерфейс, тогда в наследниках
                 возможно появление множества заглушек, а
                соответственно, много лишнего кода, который
                           неудобно поддерживать
Как бывает в жизни… (я точно видел)
А так надо… (я стараюсь так делать :-) )
Принцип инверсии зависимости (DIP)
Формулировка:
• Модули верхнего уровня не должны зависеть от модулей
  нижнего уровня. Оба должны зависеть от абстракции.
• Абстракции не должны зависеть от деталей. Детали должны
  зависеть от абстракций.




     Почему?


                         Потому что возникает паутина
                     зависимостей, превращая реализацию
                      очередного изменения требований в
                             настоящий кошмар.
Класс который слишком много знал…




•   Знает, как вычислить сумму заказа;
•   Знает, как и каким калькулятором вычислить сумму скидки;
•   Знает, что означают коды стран;
•   Знает, каким образом вычислить сумму налога для той или иной
    страны;
•   Знает формулу, по которой из всех слагаемых
    вычисляется стоимость заказа.
И что с ним стало…
                         до…
       UI Layer


                  Business Layer


                                     DataAccess Layer

                      после…

                    Business Layer
       UI Layer       Interface


                                         DataAccess Layer
                    Business Layer
                                            Interface


                                           DataAccess
                                             Layer
От чего мы хотим убежать?
 Жесткость              Хрупкость        Неподвижность




        Жесткость - изменение одной части кода затрагивает слишком
много других частей;
        Хрупкость - даже незначительное изменение в коде может
привести к совершенно неожиданным проблемам;
        Неподвижность - никакая из частей приложения не может быть
легко выделена и повторно использована.
Только S.O.L.I.D.?


               CRP
REP                        CCP


  ADP
                  SDP

         SAP
ВОПРОСЫ?

Как писать красивый код или основы SOLID

  • 1.
    Как писать красивыйкод или основы S.O.L.I.D. Пинин Денис dpinin@codereign.net
  • 2.
    Что такое S.O.L.I.D.? S- Single Responsibility Principle (SRP) (принцип единой ответственности) O - Open/Closed Principle (OCP) (принцип «открыто/закрыто») L - Liskov Substitution Principle (LSP) (принцип замещения Лискоy) I - Interface Segregation Principle (ISP) (принцип разделения интерфейса) D - Dependency Inversion Principle (DIP) (принцип инверсии зависимостей)
  • 3.
    Зачем соблюдать принципыS.O.L.I.D.? • Помогают построить архитектуру приложения, которое со временем будет проще (дешевле) поддерживать и развивать. • Помогаю писать повторно используемый код. Принципы != Правила
  • 4.
    Принцип единой ответственности(SRP) Формулировка: не должно быть больше одной причины для изменения класса Почему? Потому что это ведет к хрупкости дизайна (пишем один «функционал» - отваливается другой)
  • 5.
    А может ненадо? Неееет….
  • 6.
    Самый главный нарушительSRP– God Object: Как писать красивый код или основы S.O.L.I.D. Пинин Денис dpinin@codereign.net
  • 7.
  • 8.
    Принцип открытости/закрытости (OCP) Формулировка: программные сущности (классы, модули, функции и т.д.) должны быть открыты для расширения, но закрыты для изменения Почему? Потому что позволяет быстро и безболезненно реагировать на изменения бизнес-логики
  • 9.
    Чем плох этоткод? Заказчик: Лог продаж в файлах!? Это же отстой! Изменение требований: лог надо хранить в БД. Разработчик: Нет проблем!
  • 10.
  • 11.
  • 12.
    Принцип замещения Лисков(OCP) Формулировка №1: если для каждого объекта o1 типа S существует объект o2 типа T, который для всех программ P определен в терминах T, то поведение P не изменится, если o1 заменить на o2 при условии, что S является подтипом T. (ничего не понятно) Формулировка №2: подтипы должны быть заменяемы базовыми типами. Почему? Потому что клиентский код начинает считать производный класс разновидностью базового, и возможно появление кода, явно использующего этот факт
  • 13.
  • 14.
  • 15.
    Принцип разделения интерфейса(ISP) Формулировка: клиенты не должны зависеть от методов, которые они не используют Потому что если мы определим большой Почему? универсальный интерфейс, тогда в наследниках возможно появление множества заглушек, а соответственно, много лишнего кода, который неудобно поддерживать
  • 16.
    Как бывает вжизни… (я точно видел)
  • 17.
    А так надо…(я стараюсь так делать :-) )
  • 18.
    Принцип инверсии зависимости(DIP) Формулировка: • Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракции. • Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций. Почему? Потому что возникает паутина зависимостей, превращая реализацию очередного изменения требований в настоящий кошмар.
  • 19.
    Класс который слишкоммного знал… • Знает, как вычислить сумму заказа; • Знает, как и каким калькулятором вычислить сумму скидки; • Знает, что означают коды стран; • Знает, каким образом вычислить сумму налога для той или иной страны; • Знает формулу, по которой из всех слагаемых вычисляется стоимость заказа.
  • 20.
    И что сним стало… до… UI Layer Business Layer DataAccess Layer после… Business Layer UI Layer Interface DataAccess Layer Business Layer Interface DataAccess Layer
  • 21.
    От чего мыхотим убежать? Жесткость Хрупкость Неподвижность Жесткость - изменение одной части кода затрагивает слишком много других частей; Хрупкость - даже незначительное изменение в коде может привести к совершенно неожиданным проблемам; Неподвижность - никакая из частей приложения не может быть легко выделена и повторно использована.
  • 22.
    Только S.O.L.I.D.? CRP REP CCP ADP SDP SAP
  • 23.