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

Ответ от нейросети

sobes.tech AI

DCI (Data-Context-Interaction) — это паттерн проектирования, который разделяет бизнес-логику на три составляющие: Данные (Data), Контекст (Context) и Взаимодействие (Interaction), чтобы улучшить читаемость и поддерживаемость ООП-кода, особенно при работе с изменяющимися требованиями.

  • Данные (Data): Объекты, представляющие предметную область, содержащие только состояние (атрибуты). Они не содержат бизнес-логики.
  • Контекст (Context): Точка входа для сценария использования. Он связывает объекты данных с их ролями в рамках конкретного взаимодействия, используя их "методы ролей".
  • Взаимодействие (Interaction): Бизнес-логика сценария использования, реализованная как набор ролей и их методов. Это поведенческий аспект системы, который "накладывается" на объекты данных. Часто реализуется через примеси (mixins) или трейты (traits), которые динамически добавляют поведение объектам данных в рамках контекста.

Главная идея DCI — сделать намерения разработчика, связанные с выполнением конкретного сценария использования, явными в коде. Бизнес-логика не привязана жестко к классам данных, что позволяет одному и тому же объекту играть разные роли в разных сценариях.

Преимущества:

  • Улучшенная читаемость и понимание бизнес-логики сценария.
  • Уменьшение связанности между классами данных и поведением.
  • Более легкая поддержка и изменение существующих сценариев.
  • Сохранение чистоты объектов данных (Model в MVC).

Пример концепции: Объект Аккаунт может играть роль Источник при переводе денег и роль Получатель при зачислении. Логика перевода (вычесть из источника, добавить получателю) находится в контексте перевода, а не жестко внутри класса Аккаунт.

// Концепция: Роль TransferSource
const TransferSource = {
  decreaseBalance(amount) {
    if (this.balance < amount) {
      throw new Error("Insufficient funds");
    }
    this.balance -= amount;
  }
};

// Концепция: Роль TransferDestination
const TransferDestination = {
  increaseBalance(amount) {
    this.balance += amount;
  }
};

// Концепция: Контекст - Transfer
class TransferContext {
  constructor(sourceAccount, destinationAccount, amount) {
    // Привязка ролей к объектам данных
    Object.assign(sourceAccount, TransferSource);
    Object.assign(destinationAccount, TransferDestination);

    this.source = sourceAccount;
    this.destination = destinationAccount;
    this.amount = amount;
  }

  execute() {
    // Использование методов ролей
    this.source.decreaseBalance(this.amount);
    this.destination.increaseBalance(this.amount);
    // Дополнительная логика контекста: логирование, транзакции и т.д.
  }
}

// Пример использования:
// Допустим, есть объекты данных (обычные JS объекты)
const accountA = { name: "Account A", balance: 100 }; // Data
const accountB = { name: "Account B", balance: 50 };  // Data

try {
  const transfer = new TransferContext(accountA, accountB, 30); // Context
  transfer.execute(); // Interaction (defined within Context using Roles)

  console.log(accountA.balance); // 70
  console.log(accountB.balance); // 80
} catch (error) {
  console.error(error.message);
}

Хотя DCI не является общепринятым или широко используемым в стандартных фронтенд-фреймворках, его принципы могут быть полезны при структурировании сложной бизнес-логики, отделяя ее от простых объектов данных.