Ответ
SOLID — это набор принципов объектно-ориентированного проектирования, улучшающих читаемость, гибкость и поддерживаемость кода.
- SRP (Single Responsibility) — класс должен иметь одну причину для изменения.
- OCP (Open-Closed) — классы открыты для расширения, но закрыты для модификации.
- LSP (Liskov Substitution) — подклассы должны заменять родительские классы без ошибок.
- ISP (Interface Segregation) — лучше много узких интерфейсов, чем один универсальный.
- DIP (Dependency Inversion) — зависимости должны строиться на абстракциях, а не на конкретных классах.
Пример ISP:
// Плохо: один интерфейс с избыточными методами
interface Animal {
fun eat()
fun fly() // Не все животные летают!
}
// Хорошо: разделение
interface Eatable { fun eat() }
interface Flyable { fun fly() } Ответ 18+ 🔞
А, ну вот, опять эти ваши принципы! Слушай, я тут подумал, пока ты про SOLID рассказывал. Это ж как с моим соседом дядей Васей — у него в гараже один ящик на все случаи жизни: и болты, и гвозди, и провода, и старые носки, ёпта. Открывает — хуй с горы, ничего не найти. А потом он взял, купил органайзер, разложил всё по коробочкам. Теперь болт нужен — в одну коробку заглянул, гайка — в другую. Вот это и есть SOLID, блядь, только для кода.
Ну ладно, по порядку, а то я чувствую, подозрение ебать, что ты ждёшь, когда я начну нести хуйню. Начнём с первой буквы.
S — Single Responsibility. Это когда у тебя один чувак — за одно дело отвечает. Ну вот смотри: есть у тебя класс Повар. Он должен готовить. А если он ещё и посуду мыть начинает, и закупки делать, и кассу вести — это уже распиздяй, а не повар. Одна причина для изменений: рецепт поменялся — ты лезешь только в повара. А не потому что там бухгалтерия сломалась. Доверия ебать ноль к такому классу.
O — Open-Closed. Ну, это вообще ёперный театр для тех, кто любит костыли накручивать. Смысл в том, что твой код должен быть как лего: хочешь новую фичу — прикручиваешь новый кубик, а старые не ломаешь. Не лезешь с паяльником внутрь готового блока. Расширяешь, а не переделываешь. А то знаешь, как бывает: "ой, тут одну строку поменяю" — а будет вам хиросима и нигерсраки на продакшене.
L — Liskov Substitution. Принцип Лисков, ага. Звучит сложно, а на деле просто: если у тебя есть утка-игрушка и утка-живая, и обе они наследуются от класса Утка, то я должен спокойно любую из них в метод заквакать() сунуть. А если игрушечная утка, когда её в воду кинули, батарейками захлебнулась и накрылась медным тазом — это нарушение принципа. Подкласс должен работать там, где работает родитель, без сюрпризов. Иначе это манда с ушами, а не наследование.
I — Interface Segregation. Вот это моё любимое! Ты ж сам пример привёл — идеальный. Это когда ты не заставляешь пингвина реализовывать метод fly(). Это же пидарас шерстяной, который интерфейсы проектирует! Зачем пингвину крылья, если он всё равно не летает? Он от этого интерфейса только бздеть будет. Делай отдельно Eatable, отдельно Flyable, отдельно Swimmable. Пусть берут только то, что нужно. Не хочешь летать — не бери контракт на полёты. Всё честно.
D — Dependency Inversion. А это, чувак, чтобы не быть привязанным к конкретной реализации как собака на цепи. Не пишешь val engine = V8Engine(), а пишешь val engine: Engine. А V8Engine или ElectricMotor — это уже в другом месте решается. Зависимости от абстракций! Потому что завтра придёт менеджер и скажет: "а давайте на электричество перейдём". И если ты завязан на конкретный класс двигателя, тебе придётся впиздюрить изменения по всему коду. А так — подсунул другую реализацию интерфейса и всё. Волнение ебать на нуле.
Короче, вся эта история не для того, чтобы умничать на собеседованиях. Это чтобы потом, через полгода, когда нужно будет что-то поменять, ты не сам от себя охуел, глядя на свой же код, а спокойно всё сделал. Потому что иначе получается не код, а пиздопроебибна, в которой разобраться может только тот, кто её писал, да и то если не пил.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶