← Назад к вопросам

Какие знаешь парадигмы ООП?

1.0 Junior🔥 171 комментариев
#ООП

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Парадигмы объектно-ориентированного программирования

ООП (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 принципами это создаёт масштабируемый, поддерживаемый код.

Какие знаешь парадигмы ООП? | PrepBro