Как писать красивый код или основы solid
DESCRIPTION
В данном докладе мы рассмотрим пять основных принципов дизайна классов в объектно-ориентированном проектировании, которые известны, как принципы SOLID. А также как обеспечить достаточный уровень гибкости, связанности, управляемости, стабильности и понятности кода.TRANSCRIPT
Как писать красивый код или основы S.O.L.I.D.
Пинин Денис[email protected]
Что такое 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)
Формулировка: не должно быть больше одной причины для изменения класса
Потому что это ведет к хрупкости дизайна (пишем один «функционал» - отваливается
другой)
Почему?
А может не надо?
Неееет….
Как писать красивый код или основы S.O.L.I.D.
Пинин Денис[email protected]
Самый главный нарушительSRP – God Object:
Нарушитель побежден!
Принцип открытости/закрытости(OCP)
Формулировка: программные сущности (классы, модули, функции и т.д.) должны быть открыты для расширения, но
закрыты для изменения
Почему?
Потому что позволяет быстро и безболезненно реагировать на изменения бизнес-логики
Чем плох этот код?Заказчик: Лог продаж в файлах!? Это же отстой! Изменение требований: лог надо хранить в БД.
Разработчик: Нет проблем!
Нарушаем принцип OCP!
А так лучше?
Принцип замещения Лисков (OCP)
Формулировка №1: если для каждого объекта o1 типа S существует объект
o2 типа T, который для всех программ P определен в терминах T, то поведение P не
изменится, если o1 заменить на o2 при условии, что S является подтипом T.
(ничего не понятно)
Почему?
Потому что клиентский код начинает считать производный класс разновидностью базового, и возможно появление кода, явно использующего
этот факт
Формулировка №2: подтипы должны быть заменяемы базовыми типами.
Ошибочное наследование
Попробуем протестировать
Прямоугольник или квадрат?
Принцип разделения интерфейса (ISP)
Формулировка: клиенты не должны зависеть от методов, которые они не используют
Почему? Потому что если мы определим большой
универсальный интерфейс, тогда в наследниках возможно появление множества заглушек, а
соответственно, много лишнего кода, который неудобно поддерживать
Как бывает в жизни… (я точно видел)
А так надо… (я стараюсь так делать :-) )
Принцип инверсии зависимости (DIP)
Формулировка: • Модули верхнего уровня не должны зависеть от
модулей нижнего уровня. Оба должны зависеть от абстракции.
• Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
Почему?
Потому что возникает паутина зависимостей, превращая реализацию очередного изменения требований в
настоящий кошмар.
Класс который слишком много знал…
• Знает, как вычислить сумму заказа;• Знает, как и каким калькулятором вычислить сумму скидки;• Знает, что означают коды стран;• Знает, каким образом вычислить сумму налога для той или иной
страны;• Знает формулу, по которой из всех слагаемых вычисляется стоимость заказа.
И что с ним стало…до…
после…
UI Layer
Business Layer
DataAccess Layer
UI LayerBusiness Layer
Interface
Business LayerDataAccess
Layer Interface
DataAccess Layer
От чего мы хотим убежать?
Жесткость Хрупкость Неподвижность
Жесткость - изменение одной части кода затрагивает слишком много других частей;
Хрупкость - даже незначительное изменение в коде может привести к совершенно неожиданным проблемам;
Неподвижность - никакая из частей приложения не может быть легко выделена и повторно использована.
Только S.O.L.I.D.?
REP
SAP
CCP
SDP
CRP
ADP
ВОПРОСЫ?