Sobes.tech
Middle

Šta je MVVM arhitektonski obrazac?

sobes.tech АИ

Одговор од АИ

MVVM (Model-View-ViewModel) je arhitektonski obrazac koji strukturiše kod za razdvajanje logike aplikacije na tri međusobno povezana komponenta:

  • Model: Predstavlja podatke i poslovnu logiku. Ne zavisi od UI.
  • View: Prikazuje podatke iz ViewModel-a i šalje akcije korisnika (npr. klikove) u ViewModel. View je pasivan i ne sadrži logiku obrade podataka.
  • ViewModel: Funkcioniše kao posrednik između Modela i View-a. Pruža podatke iz Modela u formatu pogodan za prikaz i obrađuje akcije korisnika, ažurirajući Model. Često koristi mehanizme za vezivanje podataka (data binding) da automatski osveži View pri promenama podataka.

Ključni principi:

  • Dvosmerno vezivanje podataka: Promene u ViewModel-u automatski se odražavaju u View-u i obrnuto (korišćenjem odgovarajućih alata).
  • Testabilnost: ViewModel je lako testirati izolovano, jer nije povezan sa UI.
  • Razdvajanje odgovornosti: Jasno razdvajanje logike prikaza, podataka i poslovne logike olakšava razvoj i održavanje.

Često se koristi u aplikacijama sa deklarativnim UI-jem, kao što su Vue.js, React (sa nekim varijacijama), Angular.

Primer najjednostavnije strukture:

// Model
class User {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

// ViewModel
class UserViewModel {
  constructor(user) {
    this.user = user;
    this.displayName = `${user.name} (${user.age})`;
  }

  incrementAge() {
    this.user.age++;
    this.displayName = `${this.user.name} (${this.user.age})`; // Ažurira displayName za View
  }
}

// View (otprilike, kako bi izgledala u deklarativnom framework-u)
/*
<template>
  <div>
    <p>{{ userViewModel.displayName }}</p>
    <button @click="userViewModel.incrementAge()">Povećaj starost</button>
  </div>
</template>

<script>
import { User } from './model';
import { UserViewModel } from './viewModel';

export default {
  data() {
    return {
      userViewModel: new UserViewModel(new User('Ivan', 30))
    };
  }
}
</script>
*/