Какие преимущества у DI?

24 марта 2025 г.Senior Frontend
Какие преимущества у DI? | 🔁 Новости из телеграм - Ghostbase News

Какие преимущества у DI?

Dependency Injection (DI) – это паттерн проектирования, который помогает разделять зависимости и делает код гибче, тестируемее и поддерживаемее. Вместо того чтобы создавать зависимости внутри класса, они передаются (инъектируются) извне.

Почему DI полезен?

Уменьшает связность кода (Loose Coupling)

Вместо того чтобы жестко привязывать один модуль к другому, DI передает зависимости снаружи.

class UserService {

constructor() {

this.db = new Database(); // Прямо создаем зависимость

}

getUser(id) {

return this.db.findUserById(id);

}

}

С DI

class UserService {

constructor(db) {

this.db = db; // DI передает зависимость извне

}

getUser(id) {

return this.db.findUserById(id);

}

}

// Передаем нужную зависимость

const database = new Database();

const userService = new UserService(database);

Улучшает тестируемость (Unit-тесты проще)

С DI можно подменять зависимости на заглушки (mock, fake, stub).

const userService = new UserService(); // Всегда использует реальную Database

userService.getUser(1); // Как протестировать без реальной БД? 🤔

С DI (можно подменить зависимость)

class FakeDatabase {

findUserById(id) {

return { id, name: "Тестовый пользователь" };

}

}

const fakeDb = new FakeDatabase();

const userService = new UserService(fakeDb);

console.log(userService.getUser(1)); // ✅ Тест без реальной БД

Улучшает расширяемость (легко менять зависимости)

Допустим, сначала использовали MySQLDatabase, но решили перейти на MongoDatabase.

class UserService {

constructor() {

this.db = new MySQLDatabase(); // Нужно менять здесь

}

}

С DI (добавляем новую зависимость без изменения кода UserService)

const db = new MongoDatabase(); // Просто передаем другую зависимость

const userService = new UserService(db);

Упрощает управление зависимостями (через DI-контейнеры)

В крупных приложениях удобно использовать DI-контейнер (например, InversifyJS для JavaScript/TypeScript).

import "reflect-metadata";

import { Container, injectable, inject } from "inversify";

@injectable()

class Database {

findUserById(id) {

return { id, name: "База данных" };

}

}

@injectable()

class UserService {

constructor(@inject(Database) db) {

this.db = db;

}

getUser(id) {

return this.db.findUserById(id);

}

}

// Настраиваем DI-контейнер

const container = new Container();

container.bind(Database).toSelf();

container.bind(UserService).toSelf();

// Получаем объект с нужными зависимостями

const userService = container.get(UserService);

console.log(userService.getUser(1));

👉 @seniorFront