Sobes.tech
Middle+

Kaip patys įgyvendintumėte MVVM architektūros požiūrį?

sobes.tech AI

Atsakymas iš AI

MVVM (Model-View-ViewModel) yra architektūros šablonas, kuris skiria UI, vaizdo logiką ir verslo logiką.

Pagrindiniai komponentai:

  • Modelis: Atstovauja duomenis ir verslo logiką. Nėra priklausomas nuo UI.
  • View: UI sluoksnis. Rodo duomenis iš ViewModel ir siunčia naudotojo veiksmus (įvykius) į ViewModel. Neturi verslo logikos.
  • ViewModel: Laiko vaizdo logiką, paruošia duomenis iš Model, kad būtų rodomi View, ir apdoroja naudotojo veiksmus. Neturi tiesioginių nuorodų į View, sąveikauja per stebimus duomenis (Observable srautai).

Savarankiška įgyvendinimas:

  1. Modelio kūrimas: Paprasti Plain Old Java Objects (POJO) arba Kotlin duomenų klasės duomenims atstovauti, saugyklos duomenų šaltiniams (tinklas, duomenų bazė).

    // Modelio pavyzdys
    duomenų klasė User(val id: Int, val name: String, val email: String)
    
    klasė UserRepository {
        fun getUser(userId: Int): User {
            // Logika naudotojo gavimui iš duomenų šaltinio
            return User(userId, "Test User $userId", "test$userId@example.com")
        }
    }
    
  2. ViewModel kūrimas: Klasė, paveldinti iš ViewModel Android architektūros komponentų (arba savo įgyvendinimas su Lifecycle sąsaja). Laiko LiveData arba Kotlin StateFlow/SharedFlow stebimiems duomenims. Turi metodus naudotojo veiksmų apdorojimui ir duomenų atnaujinimui.

    // Pavyzdinis ViewModel
    klasė UserViewModel(private val userRepository: UserRepository) : androidx.lifecycle.ViewModel() {
    
        privatus _user = MutableLiveData<User>()
        val user: LiveData<User> = _user
    
        fun loadUser(userId: Int) {
            // Realiame taikinyje - asinchroninis įkėlimas
            val loadedUser = userRepository.getUser(userId)
            _user.value = loadedUser // LiveData atnaujinimas
        }
    
        fun updateUser(newUser: User) {
            // Logika naudotojo atnaujinimui
            _user.value = newUser
        }
    }
    
  3. View įgyvendinimas: Activity arba Fragment. Sąveikauja su ViewModel, prenumeruoja stebimus duomenis iš ViewModel, atnaujina UI duomenų pasikeitimu. Deleguoja naudotojo įvykių apdorojimą (paspaudimus, teksto įvedimą) į ViewModel. Naudoja Data Binding arba View Binding deklaratyvesniam ryšiui.

    // Pavyzdinis View (Fragment)
    klasė UserFragment : Fragment() {
    
        privatus vėluojantis viewModel: UserViewModel
        privatus _binding: FragmentUserBinding? = null
        privatus binding gauti() = _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)
    
            // Gauti ViewModel, pageidžiu naudoti ViewModelProvider
            viewModel = ViewModelProvider(this).get(UserViewModel::class.java)
    
            // Prenumeruoti stebimus duomenis
            viewModel.user.observe(viewLifecycleOwner) { user ->
                // Atnaujinti UI kai keičiasi naudotojas
                binding.userNameTextView.text = user.name
                binding.userEmailTextView.text = user.email
            }
    
            // Deleguoti įvykį į ViewModel
            binding.loadUserButton.setOnClickListener {
                viewModel.loadUser(1) // Pavyzdys: įkelti naudotoją su ID 1
            }
        }
    
        override fun onDestroyView() {
            super.onDestroyView()
            _binding = null
        }
    }
    
  4. Komponentų sujungimas: View sukuria ViewModel egzempliorių (per ViewModelProvider) ir prenumeruoja jos stebimus duomenis. ViewModel dirba su Model.

Svarbūs savarankiškos įgyvendinimo aspektai:

  • Naudojimas LiveData arba Flow reaktyvumui ir automatiškai UI atnaujinti duomenų pasikeitimu.
  • Naudojimas ViewModelProvider teisingam ViewModel gyvavimo ciklui užtikrinti.
  • Naudojimas Dependency Injection (pvz., Hilt ar Koin) priklausomybių teikimui (pvz., UserRepository) į ViewModel.
  • Asinchroninių operacijų apdorojimas (tinklų užklausos, duomenų bazės darbai) ViewModel naudojant coroutines ar kitus mechanizmus.

Privalumai tokio požiūrio:

  • Testuojamumas: ViewModel lengvai testuojamas atskirai nuo UI.
  • Atsakomybės pasidalijimas: Aiškus UI, vaizdo logikos ir verslo logikos atskyrimas.
  • Atsparumas konfigūracijos pokyčiams: ViewModel išlieka keičiant ekrano pasukimus ir kitus konfigūracijos pokyčius.
  • Pagerinta kodo palaikymas.