Sobes.tech
Senior

Šta je DCI?

sobes.tech АИ

Одговор од АИ

DCI (Data-Context-Interaction) je arhitektonski obrazac koji se fokusira na način na koji objekti međusobno deluju u određenom kontekstu kako bi izvršili određenu radnju. Cilj mu je da poboljša čitljivost i održivost koda, odvajajući podatke (Data) od ponašanja (Interaction) unutar konteksta (Context) koji deluje na njih.

  • Data (Podaci): Predstavljaju stanje objekata. Mogu biti obične klase ili strukture koje sadrže podatke.
  • Context (Kontekst): Opisuje konkretnu situaciju ili scenario u kojem dolazi do interakcije objekata. Kontekst povezuje učesnike (podatkovne objekte) sa ulogama.
  • Interaction (Interakcija): Određuje ponašanje ili logiku koja se primenjuje na učesnike konteksta. Interakcija se realizuje putem uloga koje učesnici igraju u ovom kontekstu.

Prednosti DCI:

  • Poboljšana čitljivost: Kod koji opisuje interakciju je odvojen od definicije podataka, čineći ga lakšim za razumevanje.
  • Smanjenje duplikacije koda: Ponašanje specifično za određeni scenario inkapsulira se, smanjujući potrebu za dupliranjem logike.
  • Veća fleksibilnost: Lakše je menjati ili dodavati nove scenarije interakcije bez menjanja definicija podataka.
  • Testabilnost: Pojedinačne komponente (podatci, kontekst, interakcije) su lakše za testiranje izolovano.

Primer (konceptualni):

Zamislimo scenario "prebacivanja novca" između dva bankovna računa.

  • Data: Klasa BankAccount sa poljima balance i accountNumber.
  • Context: MoneyTransferContext koji povezuje dva objekta BankAccount sa ulogama "Source" (pošiljalac) i "Destination" (primaoc).
  • Interaction: Logika prenosa novca: oduzimanje sa salda pošiljaoca i dodavanje na saldo primaoca. Ova logika se realizuje putem metoda uloga "Source" i "Destination" unutar MoneyTransferContext.
// Konceptualni primer koda (nije potpuna implementacija DCI)
class BankAccount {
  constructor(public balance: number, public accountNumber: string) {}

  // Metode specifične za podatke
  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("Nedovoljna sredstva");
    }
  }
}

// Kontekst i interakcija (ovde pomešano radi jednostavnosti)
class MoneyTransferContext {
  constructor(private source: BankAccount, private destination: BankAccount) {}

  transfer(amount: number): void {
    try {
      // Interakcija putem uloga (neizravno ovde)
      this.source.withdraw(amount);
      this.destination.deposit(amount);
      console.log(`Uspešno preneto ${amount} sa ${this.source.accountNumber} na ${this.destination.accountNumber}`);
    } catch (error: any) {
      console.error(`Neuspešan transfer: ${error.message}`);
    }
  }
}

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

const transferContext = new MoneyTransferContext(account1, account2);
transferContext.transfer(200);
transferContext.transfer(1500); // Greška zbog nedostatka sredstava

U pravom DCI, interakcija (transfer) bi bila implementirana u posebnim "uloga" metodama, koje bi "ubrizgavale" ili "dodavale" objekte BankAccount u okviru MoneyTransferContext, bez menjanja same klase BankAccount. To se postiže različitim tehnikama u zavisnosti od programskog jezika.