Цель работы Целью является демонстрация практического применения принципов SOLID на четырех задачах:
- разделение God класса обработки изображений
- выделение валидации товара из модели предметной области, 3.защита почтового отправителя от изменений за счёт абстракции подсистемы журналирования.
- Кейс хранилищ (Repository) с устранением ветвления по типам.
В данных примерах были следующие задачи:
- Устранить нарушение едиинественной ответственности в ImageHelper
- Обеспечить возможность менять правила проверки товара без изменения класса Product (Open/Closed Principle, инверсия зависимостей)
- В SmtpMailer избравить от зависимости Open/Closed Principle + расширение журналирования
- Исключить условные конструкции по типам для паттерна Repository и делегировать сохранение специализированным репозитория (Принцип Барбары Лисков, принцип единой ответственности)
Исходные проблемы:
- God object. Совмещение разнотипных функций внутри одного класса, что приводит к проблемам с усложенением тестированию, изменениями
- Валидация внутри модели - при изменении сценариев проверки, меняется метод isValid
- Смена места хранения влечет изменение SmtpMailer
Решение:
-
Разделение ImageHelper: Введены ImageFileManager, ImageProcessor, ImageDatabaseManager, ImageDownloader и фасад ImageService. Каждый класс отвечает за одну область ответственности, Компоненты возможно расширять без изменения других, классы могут зависеть от абстракций (например от интерфейса загрузчика)
-
Валидация Product: Реализована через выделения контакта ProductValudator и две реализации. Product хранит состояние, проверку осуществляют отдельные валидаторы Новое правило - новая реализация валидатора. Используется инверсия зависимостей, посредством зависимости от абстракции валидатора а не от класса
-
SmtpMailer и логирование: Введен Ilogger, реализация FileLogger, DatabaseLogger, ConsoleLogger, плюс создание фабрики LoggerFactory и SMTP Маiler. Таким образрм реализовано OCP и принцип единой ответственности + принцип подстановки Барбары Лисков
-
Единый репозиторий с условными проверками типа сущности в методе save Введён общий реестр соответствий «тип сущности → конкретный репозиторий». Клиентский код выбирает репозиторий не через ветвления, а через обращение к словарю по ключу type(entity). Для запуска добавлены простые репозитории AccountRepository и RoleRepository. Убраны ветвления по типам в прикладной функции сохранения, добавлено логиирование регистрации типа с информацией об ошибке Использованы принципы единой ответственности, подстановки Лисков и OCP
Возможно стоило инкапсулировать реестр в глобальный провайдер.