Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Парадигмы объектно-ориентированного программирования
ООП (Object-Oriented Programming) — это парадигма программирования, основанная на концепции объектов и классов. Существует четыре основных столпа ООП, которые я активно использую в разработке.
1. Инкапсуляция (Encapsulation)
Инкапсуляция — это механизм скрытия внутренней реализации объекта и предоставления контролируемого доступа через интерфейс.
// ❌ Плохо — прямой доступ к полям
class BankAccount {
balance: number = 0;
}
const account = new BankAccount();
account.balance = -1000; // Позволяет некорректное состояние
// ✅ Хорошо — инкапсуляция с контролем
class BankAccount {
private balance: number = 0;
getBalance(): number {
return this.balance;
}
deposit(amount: number): void {
if (amount <= 0) throw new Error('Amount must be positive');
this.balance += amount;
}
withdraw(amount: number): void {
if (amount > this.balance) throw new Error('Insufficient funds');
this.balance -= amount;
}
}
Преимущества:
- Контроль над состоянием объекта
- Защита от некорректных операций
- Возможность изменить реализацию без влияния на клиентский код
2. Наследование (Inheritance)
Наследование — это механизм, позволяющий создавать новые классы на основе существующих, переиспользуя и расширяя их функциональность.
// Базовый класс
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log('Some generic animal sound');
}
sleep(): void {
console.log(`${this.name} is sleeping`);
}
}
// Наследование
class Dog extends Animal {
breed: string;
constructor(name: string, breed: string) {
super(name);
this.breed = breed;
}
// Переопределение метода
makeSound(): void {
console.log('Woof! Woof!');
}
fetch(): void {
console.log(`${this.name} is fetching`);
}
}
const dog = new Dog('Rex', 'Labrador');
dog.makeSound(); // "Woof! Woof!"
dog.sleep(); // "Rex is sleeping" (унаследовано)
dog.fetch(); // "Rex is fetching" (собственный метод)
Типы наследования:
- Простое наследование — класс наследует от одного класса (TypeScript)
- Множественное наследование — от нескольких классов (не поддерживается в TS)
- Многоуровневое наследование — цепочка наследования
3. Полиморфизм (Polymorphism)
Полиморфизм — это способность объектов одного типа принимать различные формы и обрабатываться единообразно.
// Интерфейс как контракт
interface Shape {
area(): number;
perimeter(): number;
}
// Различные реализации
class Circle implements Shape {
radius: number;
constructor(radius: number) {
this.radius = radius;
}
area(): number {
return Math.PI * this.radius ** 2;
}
perimeter(): number {
return 2 * Math.PI * this.radius;
}
}
class Rectangle implements Shape {
width: number;
height: number;
constructor(width: number, height: number) {
this.width = width;
this.height = height;
}
area(): number {
return this.width * this.height;
}
perimeter(): number {
return 2 * (this.width + this.height);
}
}
// Полиморфное использование
function printShapeInfo(shape: Shape): void {
console.log(`Area: ${shape.area()}`);
console.log(`Perimeter: ${shape.perimeter()}`);
}
const shapes: Shape[] = [
new Circle(5),
new Rectangle(4, 6),
];
shapes.forEach(shape => printShapeInfo(shape));
Типы полиморфизма:
- Полиморфизм подтипов — через наследование и интерфейсы
- Параметрический полиморфизм — через generics
- Операторный полиморфизм — перегрузка операторов
4. Абстракция (Abstraction)
Абстракция — это процесс выделения существенных характеристик объекта, скрывая лишние детали.
// Абстрактный класс
abstract class Vehicle {
protected brand: string;
protected speed: number = 0;
constructor(brand: string) {
this.brand = brand;
}
// Абстрактный метод
abstract start(): void;
abstract stop(): void;
// Конкретный метод
accelerate(): void {
this.speed += 10;
console.log(`Speed: ${this.speed} km/h`);
}
}
class Car extends Vehicle {
start(): void {
console.log(`${this.brand} car engine started`);
}
stop(): void {
console.log(`${this.brand} car engine stopped`);
}
}
class Motorcycle extends Vehicle {
start(): void {
console.log(`${this.brand} motorcycle engine started`);
}
stop(): void {
console.log(`${this.brand} motorcycle engine stopped`);
}
}
SOLID принципы (расширение ООП)
SOLID — это набор принципов для написания чистого, поддерживаемого кода:
S — Single Responsibility Principle
// ❌ Плохо — класс делает слишком много
class User {
create() { /* ... */ }
delete() { /* ... */ }
sendEmail() { /* ... */ }
saveToDatabase() { /* ... */ }
}
// ✅ Хорошо — разделение ответственности
class User {
create() { /* ... */ }
delete() { /* ... */ }
}
class EmailService {
send() { /* ... */ }
}
class UserRepository {
save() { /* ... */ }
}
O — Open/Closed Principle
// ✅ Открыт для расширения, закрыт для модификации
interface PaymentMethod {
process(amount: number): void;
}
class CreditCardPayment implements PaymentMethod {
process(amount: number): void { /* ... */ }
}
class PayPalPayment implements PaymentMethod {
process(amount: number): void { /* ... */ }
}
L — Liskov Substitution Principle
// ✅ Подклассы могут заменять базовый класс
class Bird {
fly(): void { /* ... */ }
}
class Sparrow extends Bird {
fly(): void { /* летает */ }
}
class Penguin extends Bird {
fly(): void { /* не может летать! Нарушение LSP */ }
}
// Правильнее:
class Bird {}
class FlyingBird extends Bird {
fly(): void { /* ... */ }
}
class Penguin extends Bird {} // Не летает
I — Interface Segregation Principle
// ❌ Плохо — один большой интерфейс
interface Worker {
work(): void;
eat(): void;
}
// ✅ Хорошо — разделённые интерфейсы
interface Workable {
work(): void;
}
interface Eatable {
eat(): void;
}
class Robot implements Workable {
work(): void { /* ... */ }
}
class Human implements Workable, Eatable {
work(): void { /* ... */ }
eat(): void { /* ... */ }
}
D — Dependency Inversion Principle
// ❌ Плохо — зависимость от конкретного класса
class UserService {
private db = new MySQL();
}
// ✅ Хорошо — зависимость от абстракции
interface Database {
connect(): void;
}
class UserService {
constructor(private db: Database) {}
}
class MySQL implements Database {
connect(): void { /* ... */ }
}
class PostgreSQL implements Database {
connect(): void { /* ... */ }
}
Практическое применение в Node.js/NestJS
// Реальный пример из production кода
abstract class BaseRepository<T> {
protected abstract getEntity(): any;
async findById(id: string): Promise<T> {
return this.getEntity().findOne(id);
}
}
class UserRepository extends BaseRepository<User> {
protected getEntity() {
return User;
}
}
@Injectable()
class UserService {
constructor(private userRepository: UserRepository) {}
async getUserById(id: string): Promise<User> {
return this.userRepository.findById(id);
}
}
Итоги
Четыре столпа ООП работают вместе: ✓ Инкапсуляция — скрываем детали ✓ Наследование — переиспользуем код ✓ Полиморфизм — гибкость и расширяемость ✓ Абстракция — работаем с сущностями на высоком уровне
Вместе с SOLID принципами это создаёт масштабируемый, поддерживаемый код.