Sobes.tech
Senior

Čo je DCI?

sobes.tech AI

Odpoveď od AI

DCI (Data-Context-Interaction) je architektonický vzor, ktorý sa zameriava na spôsob, akým objekty v konkrétnom kontexte spolu komunikujú, aby vykonali určitú akciu. Cieľom je zlepšiť čitateľnosť a udržiavateľnosť kódu tým, že oddelí dáta (Data) od správania (Interaction) v rámci kontextu (Context), ktorý na nich pôsobí.

  • Data (Dáta): Predstavujú stav objektov. Môžu to byť bežné triedy alebo štruktúry obsahujúce dáta.
  • Context (Kontext): Popisuje konkrétnu situáciu alebo scenár, v ktorom dochádza ku komunikácii medzi objektmi. Kontext spája účastníkov (dátové objekty) s rolami.
  • Interaction (Interakcia): Určuje správanie alebo logiku, ktorá sa aplikuje na účastníkov kontextu. Interakcia je realizovaná prostredníctvom rolí, ktoré účastníci hrajú v danom kontexte.

Výhody DCI:

  • Zlepšená čitateľnosť: Kód opisujúci interakciu je oddelený od definície dát, čo ho robí zrozumiteľnejším.
  • Zníženie duplikácie kódu: Správanie špecifické pre konkrétny scenár je inkapsulované, čo znižuje potrebu duplikovať logiku.
  • Väčšia flexibilita: Je jednoduchšie meniť alebo pridávať nové scenáre interakcie bez zásahu do definície dát.
  • Testovateľnosť: Samostatné komponenty (dáta, kontext, interakcie) sú ľahšie testovateľné izolovane.

Príklad (konceptuálny):

Predstavme si scenár "prevod peňazí" medzi dvoma bankovými účtami.

  • Data: Klasa BankAccount s poľami balance a accountNumber.
  • Context: MoneyTransferContext, ktorý spája dva objekty BankAccount s rolami "Source" (izlazatel) a "Destination" (príjemca).
  • Interaction: Logika prevodu peňazí: odpočítanie z zostatku odosielateľa a pridanie k zostatku príjemcu. Táto logika je realizovaná prostredníctvom metód rolí "Source" a "Destination" v rámci MoneyTransferContext.
// Koncepčný príklad kódu (nie je úplná implementácia DCI)
class BankAccount {
  constructor(public balance: number, public accountNumber: string) {}

  // Metódy, špecifické pre dáta
  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("Nedostatok prostriedkov");
    }
  }
}

// Kontekst a interakcia (tu zmiešané pre jednoduchosť)
class MoneyTransferContext {
  constructor(private source: BankAccount, private destination: BankAccount) {}

  transfer(amount: number): void {
    try {
      // Interakcia cez role (nepriamo tu)
      this.source.withdraw(amount);
      this.destination.deposit(amount);
      console.log(`Úspešne prevedených ${amount} z ${this.source.accountNumber} na ${this.destination.accountNumber}`);
    } catch (error: any) {
      console.error(`Neuspešný transfer: ${error.message}`);
    }
  }
}

// Použitie
const account1 = new BankAccount(1000, "123");
const account2 = new BankAccount(500, "456");

const transferContext = new MoneyTransferContext(account1, account2);
transferContext.transfer(200);
transferContext.transfer(1500); // Chyba kvôli nedostatku prostriedkov

V skutočnom DCI by bola interakcia (transfer) implementovaná v samostatných "rolových" metódach, ktoré by "injektovali" alebo "pridávali" k objektom BankAccount v rámci MoneyTransferContext, bez zmeny samotnej triedy BankAccount. To je možné dosiahnuť rôznymi technikami v závislosti od programovacieho jazyka.