Sobes.tech
Middle+

Hogyan valósítanád meg saját magad az MVVM architekturális megközelítést?

sobes.tech MI

Válasz az MI-től

MVVM (Model-View-ViewModel) egy architektúra mintázat, amely elválasztja a UI-t, a megjelenítési logikát és az üzleti logikát.

Fő komponensek:

  • Model: Adatokat és üzleti logikát képvisel. Nem függ a UI-tól.
  • View: UI réteg. Megjeleníti a ViewModel-ből származó adatokat, és küldi a felhasználói műveleteket (eseményeket) a ViewModel-nek. Nem tartalmaz üzleti logikát.
  • ViewModel: Tartalmazza a megjelenítési logikát, előkészíti az adatokat a Model-ből a View megjelenítéséhez, és feldolgozza a felhasználói műveleteket. Nincs közvetlen hivatkozása a View-ra, megfigyelhető adatok (Observable streams) révén lép kapcsolatba.

Önálló megvalósítás:

  1. Model létrehozása: Egyszerű Java POJO vagy Kotlin adat osztályok az adatok reprezentálására, repository-k az adatforrásokhoz való hozzáféréshez (hálózat, adatbázis).

    // Modell példa
    data class User(val id: Int, val name: String, val email: String)
    
    class UserRepository {
        fun getUser(userId: Int): User {
            // Logika a felhasználó lekéréséhez az adatforrásból
            return User(userId, "Test User $userId", "test$userId@example.com")
        }
    }
    
  2. ViewModel létrehozása: Osztály, amely öröklődik az ViewModel-ból az Android Architecture Components-ből (vagy saját megvalósítás életciklus-tudatossággal). Tartalmaz LiveData vagy Kotlin StateFlow/SharedFlow-t megfigyelhető adatokhoz. Metódusokat tartalmaz a felhasználói műveletek feldolgozására és az adatok frissítésére.

    // Példa ViewModel
    class UserViewModel(private val userRepository: UserRepository) : androidx.lifecycle.ViewModel() {
    
        private val _user = MutableLiveData<User>()
        val user: LiveData<User> = _user
    
        fun loadUser(userId: Int) {
            // Való életben - aszinkron betöltés
            val loadedUser = userRepository.getUser(userId)
            _user.value = loadedUser // LiveData frissítése
        }
    
        fun updateUser(newUser: User) {
            // Felhasználó frissítési logika
            _user.value = newUser
        }
    }
    
  3. View megvalósítása: Activity vagy Fragment. Kapcsolódik a ViewModel-hez, feliratkozik a ViewModel megfigyelhető adataira, és frissíti a UI-t az adatok változásakor. Delegálja a felhasználói események (kattintások, szövegbevitel) feldolgozását a ViewModel-nek. Data Binding vagy View Binding használata a deklaratívabb kötéshez.

    // Példa View (Fragment)
    class UserFragment : Fragment() {
    
        private lateinit var viewModel: UserViewModel
        private var _binding: FragmentUserBinding? = null
        private val binding get() = _binding!!
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View {
            _binding = FragmentUserBinding.inflate(inflater, container, false)
            return binding.root
        }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            // ViewModel beszerzése, legjobb a ViewModelProvider segítségével
            viewModel = ViewModelProvider(this).get(UserViewModel::class.java)
    
            // Megfigyelhető adatok feliratkozás
            viewModel.user.observe(viewLifecycleOwner) { user ->
                // UI frissítése
                binding.userNameTextView.text = user.name
                binding.userEmailTextView.text = user.email
            }
    
            // Esemény delegálása a ViewModel-nek
            binding.loadUserButton.setOnClickListener {
                viewModel.loadUser(1) // Példa: felhasználó betöltése ID 1-gyel
            }
        }
    
        override fun onDestroyView() {
            super.onDestroyView()
            _binding = null
        }
    }
    
  4. Komponensek összekapcsolása: A View példányt hoz létre a ViewModel-ből (a ViewModelProvider segítségével), és feliratkozik a megfigyelhető adatokra. A ViewModel a Model-lel dolgozik.

A fő szempontok az önálló megvalósításban:

  • A LiveData vagy Flow használata a reaktivitás és az automatikus UI-frissítés érdekében az adatok változásakor.
  • A ViewModelProvider használata a ViewModel helyes életciklusának biztosítására.
  • Dependency Injection (pl. Hilt vagy Koin) alkalmazása a függőségek (pl. UserRepository) biztosítására a ViewModel-ben.
  • Aszinkron műveletek (hálózati kérések, adatbázis-kezelés) kezelése a ViewModel-ben coroutine-k vagy más mechanizmusok segítségével.

Az ilyen megközelítés előnyei:

  • Tesztelhetőség: A ViewModel könnyen tesztelhető külön az UI-tól.
  • Felelősségek szétválasztása: Világos szétválasztás az UI, a prezentációs logika és az üzleti logika között.
  • A konfigurációs változásokkal szembeni ellenállás: A ViewModel megmarad képernyőforgatás és más konfigurációs változások során.
  • Kódkarbantartás javítása.