- PVSM.RU - https://www.pvsm.ru -
Disclaimer: Всем можно, ну а я чем хуже!?
SOLID — это набор принципов по организации кода. Фактически они декларируют некие правила, которые помогут вам сохранить свои и чужие нервы и время. А могут и не помочь.
Попробуем разобраться в этих принципах на пальцах, без примеров кода и СМС.
Должна быть одна и только одна причина для изменения класса («A class should have only one reason to change.» Robert C. Martin.)
Представим, что у вас на компе лежит пяток любимых песен, пара фильмов и фотки котиков. Вы валите все это в «Мои документы» и, в целом, радуетесь жизни.
Потом вы качаете еще фильмов, новый альбом любимой группы и десяток новых котиков. В «Моих документах» становится как-то не комфортно и вы раскладываете все по папочкам.
Музыка Фильмы Котики
Потом вы подключаете скоростной безлимит, срываетесь с катушек и качаете все серии Симпсонов, полные дискографии любимых групп, а к фоткам котиков добавляются фотки из поездки на рыбалку с друзьями. Папочки начинают ветвиться.
Музыка
The Doors
Waiting for the Sun
Hello, I Love You.mp3
...
...
RHCP
Агутин
Видео
Сериалы
Фильмы
Студия Private
Фото
Котики
Рыбалка
Преферанс на даче
куртизанки
И что мы тут имеем?
Какая может быть причина изменения «The Doors»? Только одна — (качественное или количественное) изменение песен группы The Doors. А вот удаление надоевшего сериала из "/Видео/Сериалы/" такой причиной никак не может являться, так-же как и переименование «Музыка» в «Music».
Какие можно сделать выводы?
Программные сущности (классы, модули, функции и т.п.) должны быть открыты для расширения, но закрыты для изменения («Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.» Bertrand Meyer)
Вернемся к тому шагу нашей истории, когда вы подключили скоростной безлимит. Допустим, что в первую очередь вы накачали всевозможных фильмом про сантехников кинокомпании Private и, так как они все были про сантехников, создали папку "/Видео/Про сантехников/".
Через некоторое время вы скачали еще фильмов этой студии, но уже про доставку пиццы. Мало того, ваша новая девушка написала вам СМС «Я скачала фильм „Афоня“ и сохранила его в папку /Видео/Про сантехников/, ок?». И вроде бы все верно — про сантехника, но есть нюанс.
И тут вам становится понятно, что изменение функциональности невозможно без модификации уже существующей структуры папок(классов), а это явное нарушение принципа OCP.
Как в этом случае надо было сделать? Очень просто — изначально спроектировать систему таким образом, чтобы новый функционал не требовал изменения старого кода. Т.е. не хардкодить папку "../Про сантехников/", надеясь, что в будущем там только про них и будет, а повысить уровень абстракции до "../Студия Private/" и спокойно скармливать ей и сантехников и разносчиков пиццы и прочая-прочая…
А для Афони создать новый класс, например "../Мосфильм/", расширив класс "/Видео/"
Выводы:
Объекты в программе должны быть заменяемыми на экземпляры их подтипов без изменения правильности выполнения программы.
Ну тут совсем просто.
Для объяснения давайте обратимся к милоте и няшности, а конкретно к папке "/Фото/Котики/".
Котиков мы любим и фотографий собрано у нас очень много.
Фото
Котики
Рыжие
Полосатые
Мокрые
Черные
Манулы
Бывает даже прямо запускаем слайдшоу по всей корневой папке и любуемся. И вот, в один прекрасный момент, когда вы уже практически достигли нирваны, на экран выводится:
Невозможно отобразить файл "/Фото/Котики/Книги/Кот в сапогах.fb2"
Как потом выяснилось, ваша подруга решила поднять градус милоты и отнаследовала «Котики» новой подпапкой «Книги», грубо нарушив LSP, так как подкласс «Книги» ну никак нельзя использовать вместо базового класса «Фото».
Выводы:
Клиенты не должны зависеть от методов, которые они не используют.
Вот тут с папочками и файликами объяснить будет сложно, но я попробую — не судите строго за некоторую натянутость.
Вам надоел стандартный проигрыватель музыки и вы решили скачать новый, супер модный и хайповый. Он даже умеет отображать обложку музыкального альбома и выводить субтитры исполняемой песни. Но вот беда, если в папке альбома отсутствуют файлы «cover.jpg» и «subtitles.txt», то проигрыватель падает с ошибкой. И вот вы, проклиная все на свете, начинаете создавать во всех подпапках с альбомами эти файлы заглушки.
Т.е., проводя не корректные аналогии, мы обязали класс «Музыка» и всех его наследников реализовывать интерфейс «AudioCoverSubtitles». При этом, полностью этот интерфейс реализует только альбом «Waiting for the Sun», альбом «The best of The Doors» реализует только часть «Audio+Cover», а все остальные только «Audio».
Это подводит нас к мысли, что имеет смысл разделить толстый интерфейс «AudioCoverSubtitles» на три небольших «Audio», «Cover» и «Subtitles» и применять их только там, где они действительно нужны.
Выводы:
Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций.
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
Модуль «The Doors» не должен зависеть от того, какого рода аудио файлы в нем сложены, .mp3, .flac или .wav.
Модуль «The Doors», его подмодуль «Waiting for the Sun» (и все остальные), зависят от верхнеуровневой абстракции «Музыка», которая определяет их реализацию (то, что внутри у них музыка).
Допустим мы решили разделить хранение музыки по принципу сжатия — «с потерями» и «без потерь». Это детали, которые объединяет зависимость от абстракции «Музыка» — в них, в конечном итоге, должна таки быть музыка. При этом сама абстракция «Музыка» не зависит от этих деталей. Ей все равно, с потерями там музыка или без них — она как была музыкой, так ей и остается.
Выводы:
Спасибо за внимание и хороших выходных!
Автор: rjhdby
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/oop/282421
Ссылки в тексте:
[1] Источник: https://habr.com/post/413707/?utm_campaign=413707
Нажмите здесь для печати.