Sobes.tech
Senior

DCI чист?

sobes.tech AI

Ҷавоб аз AI

DCI (Data-Context-Interaction) як патерн архітектури, який зосереджений на тому, як об'єкти взаємодіють у конкретному контексті для виконання певної дії. Його мета — покращити читабельність і підтримуваність коду, розділяючи дані (Data) від поведінки (Interaction) у межах контексту (Context), що діє на них.

  • Data (Дані): Представляє стан об'єктів. Це можуть бути звичайні класи або структури, що містять дані.
  • Context (Контекст): Описує конкретну ситуацію або сценарій, у якому відбувається взаємодія об'єктів. Контекст зв'язує учасників (об'єкти даних) з ролями.
  • Interaction (Взаємодія): Визначає поведінку або логіку, що застосовується до учасників контексту. Взаємодія реалізується через ролі, які грають учасники у цьому контексті.

Переваги DCI:

  • Покращена читабельність: Код, що описує взаємодію, відокремлений від визначення даних, що робить його більш зрозумілим.
  • Зменшення дублювання коду: Поведінка, специфічна для конкретного сценарію, інкапсульована, що зменшує необхідність дублювати логіку.
  • Більша гнучкість: Легше змінювати або додавати нові сценарії взаємодії, не торкаючись визначень даних.
  • Тестованість: Окремі компоненти (дані, контекст, взаємодії) легше тестувати ізольовано.

Приклад (концептуальний):

Уявімо сценарій "переведення грошей" між двома банківськими рахунками.

  • Data: Клас BankAccount з полями balance і accountNumber.
  • Context: MoneyTransferContext, який зв'язує два об'єкти BankAccount з ролями "Source" (відправник) і "Destination" (одержувач).
  • Interaction: Логіка переведення грошей: віднімання з балансу відправника і додавання до балансу одержувача. Ця логіка реалізується через методи ролей "Source" і "Destination" у MoneyTransferContext.
// Концептуальний приклад коду (не є повною реалізацією DCI)
class BankAccount {
  constructor(public balance: number, public accountNumber: string) {}

  // Методи, що стосуються даних
  getBalance(): number {
    return this.balance;
  }

  deposit(amount: number): void {
    this.balance += amount;
  }

  withdraw(amount: number): void {
    if (this.balance >= amount) {
      this.balance -= amount;
    } else {
      throw new Error("Недостатньо коштів");
    }
  }
}

// Контекст і взаємодія (тут змішано для простоти)
class MoneyTransferContext {
  constructor(private source: BankAccount, private destination: BankAccount) {}

  transfer(amount: number): void {
    try {
      // Взаємодія через ролі (неявно тут)
      this.source.withdraw(amount);
      this.destination.deposit(amount);
      console.log(`Успішно переведено ${amount} з ${this.source.accountNumber} до ${this.destination.accountNumber}`);
    } catch (error: any) {
      console.error(`Не вдалося перевести гроші: ${error.message}`);
    }
  }
}

// Використання
const account1 = new BankAccount(1000, "123");
const account2 = new BankAccount(500, "456");

const transferContext = new MoneyTransferContext(account1, account2);
transferContext.transfer(200);
transferContext.transfer(1500); // Помилка через недостатні кошти