Sobes.tech
Junior

Mis on MVC arhitektuurimuster?

sobes.tech AI

Vastus AI-lt

MVC (Mudeli-Vaate-Kontroller) — see on arhitektuuriline muster, mis jagab rakenduse kolme omavahel seotud ossa, et parandada koodi organiseeritust ning lihtsustada arendust ja hooldust:

  • Mudeli (Model): esindab andmeid ja äriloogikat. vastutab andmete saamise, salvestamise ja töötlemise eest ning nende andmete haldamise reeglite eest. ei oma otsest seost kasutajaliidesega:
  • Vaate (View): vastutab andmete kuvamise eest kasutajale. saab andmeid Mudelist ja visualiseerib need. ei sisalda äriloogikat ning ei tööta otse andmetega, välja arvatud nende kuvamiseks:
  • Kontrolleri (Controller): toimib vahendajana Mudeli ja Vaate vahel. töötleb kasutaja interaktsioone (näiteks klikkimised, andmete sisestamine), saab andmeid Mudelist, edastab need Vaatele kuvamiseks ning uuendab Mudelit kasutaja tehtud muudatuste korral:

Peamised seosed:

  • Kasutaja suhtleb Vaatega:
  • Vaade edastab kasutaja tegevused Kontrollerile:
  • Kontroller töötleb kasutaja tegevusi, suheldes Mudeliga (nõuab andmeid või uuendab neid):
  • Mudel teavitab Kontrollerit (või mõnedes variatsioonides — Vaadet) andmete muutustest:
  • Kontroller uuendab Vaadet Mudeli muudatuste põhjal (või Vaade uuendatakse iseseisvalt otse Mudeliga suhtlemisel):

Eelised:

  • Vastutuste jaotus (Separation of Concerns): lihtsustab komponentide arendust, testimist ja hooldust:
  • Koodi korduvkasutus: Mudelit ja Kontrollerit saab kasutada erinevate Vaadetega:
  • Testimise lihtsustamine: komponendid saab testida sõltumatult:
  • Paralleelne arendus: erinevad meeskonnad saavad töötada samaaegselt erinevate osade (Mudel, Vaade, Kontroller) kallal:

Puudused:

  • Suurenenud keerukus: väikeste rakenduste jaoks võib olla liig:
  • "Paks Kontroller" probleem: Kontroller võib muutuda liiga suureks ja keeruliseks, kui ei järgita jaotuse põhimõtteid:
  • Piiride määramise keerukus: mõnikord on raske selgelt määratleda, kus üks komponent lõpeb ja teine algab:

Näide (skeemiline):

// Mudel (näiteks andmetega töötamise klass)
class UserModel {
  constructor() {
    this.users = [{
      id: 1,
      name: 'Alice'
    }, {
      id: 2,
      name: 'Bob'
    }];
  }

  getUsers() {
    return this.users;
  }

  addUser(user) {
    this.users.push(user);
    // Muudatuste teavitamine (tõelises rakenduses — sündmuste kaudu)
  }
}

// Vaade (näiteks nimekirja kuvamise funktsioon)
function renderUserList(users) {
  const list = document.getElementById('user-list');
  list.innerHTML = users.map(user => `<li>${user.name}</li>`).join('');
}

// Kontroller (töötluseks ja koordineerimiseks)
class UserController {
  constructor(model, view) {
    this.model = model;
    this.view = view;

    // Algse vaate uuendamine
    this.updateView();

    // Sündmuste töötleja (näiteks nupu klõps)
    document.getElementById('add-user-button').addEventListener('click', () => {
      const newUser = {
        id: this.model.getUsers().length + 1,
        name: prompt('Sisestage kasutaja nimi:')
      };
      if (newUser.name) {
        this.model.addUser(newUser);
        this.updateView(); // Vaate uuendamine pärast muutust
      }
    });
  }

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

// Kasutamine
const model = new UserModel();
const controller = new UserController(model, renderUserList);

See on lihtsustatud näide, mis illustreerib põhiprintsiipi. Reaalsetes raamistikutes (näiteks Angular, React, Vue) kasutatakse selle ja teiste arhitektuurimustrite keerukamaid variatsioone.