В данном докладе мы рассмотрим пять основных принципов дизайна классов в объектно-ориентированном проектировании, которые известны, как принципы SOLID. А также как обеспечить достаточный уровень гибкости, связанности, управляемости, стабильности и понятности кода.
Ruby - или зачем мне еще один язык программирования?
Как писать красивый код или основы 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)
Формулировка: не должно быть больше одной причины для
изменения класса
Почему?
Потому что это ведет к хрупкости дизайна (пишем
один «функционал» - отваливается другой)
8. Принцип открытости/закрытости
(OCP)
Формулировка: программные сущности
(классы, модули, функции и т.д.) должны быть открыты для
расширения, но закрыты для изменения
Почему?
Потому что позволяет быстро и безболезненно
реагировать на изменения бизнес-логики
9. Чем плох этот код?
Заказчик: Лог продаж в файлах!?
Это же отстой! Изменение
требований: лог надо хранить в БД.
Разработчик:
Нет проблем!
12. Принцип замещения Лисков (OCP)
Формулировка №1: если для каждого объекта
o1 типа S существует объект o2 типа T, который
для всех программ P определен в терминах T, то
поведение P не изменится, если o1 заменить на
o2 при условии, что S является подтипом T.
(ничего не понятно)
Формулировка №2: подтипы должны быть заменяемы базовыми типами.
Почему?
Потому что клиентский код начинает считать
производный класс разновидностью базового, и
возможно появление кода, явно использующего этот
факт
15. Принцип разделения интерфейса (ISP)
Формулировка: клиенты не должны зависеть от
методов, которые они не используют
Потому что если мы определим большой
Почему? универсальный интерфейс, тогда в наследниках
возможно появление множества заглушек, а
соответственно, много лишнего кода, который
неудобно поддерживать
18. Принцип инверсии зависимости (DIP)
Формулировка:
• Модули верхнего уровня не должны зависеть от модулей
нижнего уровня. Оба должны зависеть от абстракции.
• Абстракции не должны зависеть от деталей. Детали должны
зависеть от абстракций.
Почему?
Потому что возникает паутина
зависимостей, превращая реализацию
очередного изменения требований в
настоящий кошмар.
19. Класс который слишком много знал…
• Знает, как вычислить сумму заказа;
• Знает, как и каким калькулятором вычислить сумму скидки;
• Знает, что означают коды стран;
• Знает, каким образом вычислить сумму налога для той или иной
страны;
• Знает формулу, по которой из всех слагаемых
вычисляется стоимость заказа.
20. И что с ним стало…
до…
UI Layer
Business Layer
DataAccess Layer
после…
Business Layer
UI Layer Interface
DataAccess Layer
Business Layer
Interface
DataAccess
Layer
21. От чего мы хотим убежать?
Жесткость Хрупкость Неподвижность
Жесткость - изменение одной части кода затрагивает слишком
много других частей;
Хрупкость - даже незначительное изменение в коде может
привести к совершенно неожиданным проблемам;
Неподвижность - никакая из частей приложения не может быть
легко выделена и повторно использована.