Sobes.tech
Junior

Co je to architektonický vzor MVC?

sobes.tech AI

Odpověď od AI

MVC (Model-View-Controller) je architektonický vzor, ktorý rozdeľuje aplikáciu na tri prepojené časti na zlepšenie organizácie kódu a uľahčenie vývoja a údržby:

  • Model (Model): Reprezentuje údaje a biznis logiku. Zodpovedá za získavanie, ukladanie a spracovanie údajov, ako aj za pravidlá, ktoré tieto údaje riadia. Nemá priame zobrazenie používateľského rozhrania.
  • View (Zobrazenie): Zodpovedá za zobrazovanie údajov používateľovi. Získa údaje z Modelu a vizualizuje ich. Neobsahuje biznis logiku a neinteraguje priamo s údajmi, okrem ich vykreslenia.
  • Controller (Riadič): Pôsobí ako sprostredkovateľ medzi Modelom a Zobrazením. Spracováva interakcie s používateľom (napríklad kliknutia, zadávanie údajov), získava údaje z Modelu, odovzdáva ich Zobrazeniu na zobrazenie a aktualizuje Model pri zmenách údajov iniciovaných používateľom.

Hlavné vzťahy:

  • Používateľ interaguje so Zobrazením.
  • Zobrazenie odovzdáva akcie používateľa Controllerovi.
  • Controller spracováva akcie používateľa, interagujúc s Modelom (žiada údaje alebo ich aktualizuje).
  • Model oznamuje Controllerovi (alebo priamo Zobrazeniu, v niektorých variantoch vzoru) o zmenách údajov.
  • Controller aktualizuje Zobrazenie na základe zmien v Modeli (alebo Zobrazenie sa aktualizuje samostatne pri priamej interakcii s Modelom).

Výhody:

  • Oddelenie zodpovedností (Separation of Concerns): Zjednodušuje vývoj, testovanie a údržbu jednotlivých komponentov.
  • Opätovné použitie kódu: Model a Controller môžu byť použité s rôznymi Zobrazeniami.
  • Uľahčenie testovania: Komponenty môžu byť testované nezávisle.
  • Paralelný vývoj: Rôzne tímy môžu pracovať na rôznych častiach (Model, Zobrazenie, Controller) súčasne.

Nevýhody:

  • Zvýšená zložitosť: Pre malé aplikácie môže byť nadbytočný.
  • Problém "Fat Controller": Controller môže byť príliš veľký a zložitý, ak sa nedodržiavajú princípy rozdelenia.
  • Ťažkosti s definovaním hraníc: Niekedy je ťažké presne určiť, kde končí jeden komponent a začína druhý.

Príklad (schematický):

// Model (napríklad trieda na prácu s údajmi)
class UserModel {
  constructor() {
    this.users = [{
      id: 1,
      name: 'Alice'
    }, {
      id: 2,
      name: 'Bob'
    }];
  }

  getUsers() {
    return this.users;
  }

  addUser(user) {
    this.users.push(user);
    // Oznámenie o zmene (v reálnych aplikáciách - cez udalosti)
  }
}

// View (napríklad funkcia na vykreslenie zoznamu)
function renderUserList(users) {
  const list = document.getElementById('user-list');
  list.innerHTML = users.map(user => `<li>${user.name}</li>`).join('');
}

// Controller (na spracovanie udalostí a koordináciu)
class UserController {
  constructor(model, view) {
    this.model = model;
    this.view = view;

    // Inicializácia zobrazenia
    this.updateView();

    // Spracovanie udalostí (napríklad kliknutie na tlačidlo)
    document.getElementById('add-user-button').addEventListener('click', () => {
      const newUser = {
        id: this.model.getUsers().length + 1,
        name: prompt('Zadajte meno používateľa:')
      };
      if (newUser.name) {
        this.model.addUser(newUser);
        this.updateView(); // Aktualizácia zobrazenia po zmene modelu
      }
    });
  }

  updateView() {
    const users = this.model.getUsers();
    this.view(users);
  }
}

// Použitie
const model = new UserModel();
const controller = new UserController(model, renderUserList);

Toto je zjednodušený príklad demonštrujúci základný princíp. V skutočných frameworkoch (ako Angular, React, Vue) sa používajú pokročilejšie variácie tohto a iných architektonických vzorov.