Ответ
SOLID — основные принципы ООП:
- Single Responsibility — класс должен решать только одну задачу.
- Open-Closed — классы должны быть открыты для расширения, но закрыты для изменений.
- Liskov Substitution — подклассы должны заменять родительские классы без ошибок.
- Interface Segregation — лучше много узких интерфейсов, чем один универсальный.
- Dependency Inversion — зависимости должны строиться на абстракциях, а не на конкретных классах.
DRY (Don’t Repeat Yourself) — избегай дублирования кода.
KISS (Keep It Simple, Stupid) — простота важнее избыточной сложности.
YAGNI (You Aren’t Gonna Need It) — не добавляй функциональность "на будущее".
Пример SOLID (TypeScript):
// Принцип единственной ответственности
class Logger {
log(message: string) {
console.log(message);
}
}
class UserService {
constructor(private logger: Logger) {}
saveUser(user: User) {
// логика сохранения
this.logger.log(`User saved: ${user.name}`);
}
} Ответ 18+ 🔞
А, смотри-ка, опять про эти ваши принципы! Ну ладно, давай разжую, как для дебила, только без мата... Хотя, блядь, куда ж без него.
Вот смотри, есть такая штука — SOLID. Это не про то, что твой код должен быть твёрдым, как член с похмелья. Это пять правил, чтобы твои классы не превращались в такое монструозное говно, которое потом сам же и будешь разгребать.
- S — Single Responsibility (Принцип единственной ответственности). Это как с мужиком в доме. Один хуярит на работе, другой — с детьми сидит, третий — жрачку готовит. Нельзя, чтобы один чувак был и сантехником, и электриком, и крёстным отцом твоих детей одновременно. Класс должен делать что-то одно. Не пытайся впихнуть в
UserServiceлогику отправки email, логирования и расчёта налогов. Получится пиздец, а не класс. Смотри:
// ПЛОХО: Этот урод делает всё
class UserManager {
saveUser() { /* ... */ }
sendEmail() { /* ... */ }
generateReport() { /* ... */ }
logActivity() { /* ... */ }
}
// ХОРОШО: Каждый занимается своим делом, как в хорошей шараге
class UserRepository {
saveUser(user: User) { /* ... */ }
}
class EmailService {
sendEmail(to: string) { /* ... */ }
}
class Logger {
log(message: string) { /* ... */ }
}
-
O — Open-Closed (Открыт для расширения, закрыт для изменений). Представь, у тебя есть класс
ReportGenerator. Тебе начальник говорит: «А сделай-ка, чтобы отчёт ещё в PDF и в Excel выгружался». Если ты полезешь внутрь этого класса и начнёшь там ковыряться, добавляяif (format === 'pdf'), то ты мудак. Ты должен сделать так, чтобы можно было добавить новую фичу (новый формат), не ломая и не меняя старый, работающий код. Через интерфейсы, абстракции, вот это всё. -
L — Liskov Substitution (Подстановки Барбары Лисков). Звучит, как диагноз, но суть проста. Если у тебя есть класс
Уткас методомлетать(), и от него наследуется классРезиноваяУтка, то эта резиновая уёбыш должна тоже уметьлетать(). Или хотя бы не выёбываться и не кидать ошибку. Иначе подставить её вместо обычной утки не получится — программа ебнется. Наследник должен полностью заменять родителя. Если не может — твоя архитектура хуйня. -
I — Interface Segregation (Разделение интерфейсов). Это про то, что не надо делать один интерфейс
IMegaWorkerс методамиписатьКод(),тестировать(),кофеВарить()иподтиратьЖопуБоссу(). Если у тебя есть классСтажёр, который только кофе варит, он всё равно будет вынужден реализовывать ВСЕ методы, даже те, что ему нахуй не сдались. Делай много маленьких и узких интерфейсов:ICoder,ITester,ICoffeeMaker. Бери только то, что нужно. Не тащи на себе всё, как последний олень. -
D — Dependency Inversion (Инверсия зависимостей). Высокоуровневые модули (логика приложения) не должны зависеть от низкоуровневых (работа с базой, файловой системой, API). И те, и другие должны зависеть от абстракций (интерфейсов). Проще говоря, твой сервис не должен кричать «Дай мне PostgreSQL драйвер версии 15.4!». Он должен говорить: «Мне нужен какой-нибудь клиент для базы данных, который умеет
executeQuery». А уж что ты ему подсунешь — Postgres, MySQL или файлик на диске — ему похуй. Гибкость, ёпта!
А теперь про остальные три буквы, которые все любят повторять, но нихуя не соблюдают.
DRY (Don’t Repeat Yourself — Не Повторяйся). Если ты скопипастил один и тот же кусок кода в трёх разных местах, ты — говнокодер. Вынеси это в отдельную функцию, класс, хелпер. Потому что когда придёт время это менять, ты забудешь один из этих мест, всё сломается, и тебе придётся ебаться в три смены. Не создавай себе проблем на ровном месте.
KISS (Keep It Simple, Stupid — Будь Проще, Дурак). Не выёбывайся. Не пихай паттерны ради паттернов. Не создавай десятиуровневую абстракцию для задачи, которая решается в три строчки. Самый простой работающий код — лучший код. Сложность — это враг. Врага надо, как Муму, топить в пизду нахуй.
YAGNI (You Aren’t Gonna Need It — Тебе Это Не Понадобится). Самое важное правило для всех архитекторов-недоучек. Не пили фичи «на будущее», «а вдруг пригодится». Не добавляй в интерфейс методы, которые сейчас не используются. 99%, что они не понадобятся никогда, а вот поддерживать и тестировать этот хлам тебе придётся всегда. Делай только то, что требуется прямо сейчас. Всё остальное — похуй.
Вот и вся философия. Следуешь ей — живешь как человек. Не следуешь — получаешь легаси-проект, который все ненавидят, и в котором любое изменение стоит, как чугунный мост. Выбор за тобой, дружище.