Join our FREE personalized newsletter for news, trends, and insights that matter to everyone in America

Newsletter
New

Harmonyos Flutter Mvvm Architecture Pattern

Card image cap

HarmonyOS Next

Preface

Implementing the MVVM (Model-View-ViewModel) architecture in Flutter separates the UI (View) from business logic (Model and ViewModel), enhancing code maintainability and readability.

Overall Architecture Overview

Model

  • Role: Data layer responsible for business logic and data management.
  • Example: Manages a counter value and increment logic.

View

  • Role: User interface layer for displaying data and handling user input.
  • Example: Displays the counter value and a button to increment it.

ViewModel

  • Role: Acts as an intermediary between Model and View.

Responsibilities

:

  • Exposes data to the View.
  • Handles user input (e.g., button taps).
  • Notifies the View to update when data changes.

Detailed File Explanation

main.dart

import 'package:flutter/material.dart';  
import 'package:mvvm/View/MyHomePage.dart';  
import 'package:provider/provider.dart';  
import 'Model/Model.dart';  
import 'ViewModel/CounterViewModel.dart';  
  
void main() {  
  runApp(const MyApp());  
}  
  
class MyApp extends StatelessWidget {  
  const MyApp({super.key});  
  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      title: 'Flutter MVVM Example',  
      home: ChangeNotifierProvider(  
        create: (context) => CounterViewModel(CounterModel()),  
        child: MyHomePage(),  
      ),  
    );  
  }  
}  

Key Points:

  • Uses ChangeNotifierProvider to share CounterViewModel across the app.
  • MyHomePage accesses the ViewModel via Provider.of.

CounterViewModel.dart

import 'package:flutter/foundation.dart';  
import '../Model/Model.dart';  
  
class CounterViewModel extends ChangeNotifier {  
  final CounterModel _counterModel;  
  
  CounterViewModel(this._counterModel);  
  
  int get counter => _counterModel.counter;  
  
  void incrementCounter() {  
    _counterModel.increment();  
    notifyListeners();  
  }  
}  

Key Points:

  • Extends ChangeNotifier to enable reactive updates.
  • incrementCounter() updates the Model and triggers UI refresh.

MyHomePage.dart

import 'package:flutter/cupertino.dart';  
import 'package:flutter/material.dart';  
import 'package:provider/provider.dart';  
import '../ViewModel/CounterViewModel.dart';  
  
class MyHomePage extends StatefulWidget {  
  MyHomePage({super.key});  
  
  @override  
  State<MyHomePage> createState() => MyHomePageState();  
}  
  
class MyHomePageState extends State<MyHomePage> {  
  @override  
  Widget build(BuildContext context) {  
    final counterViewModel = Provider.of<CounterViewModel>(context);  
  
    return Scaffold(  
      appBar: AppBar(title: Text('Flutter MVVM Example')),  
      body: Center(  
        child: Column(  
          mainAxisAlignment: MainAxisAlignment.center,  
          children: <Widget>[  
            Text('Flutter HarmonyOS MVVM Principle (Dart)'),  
            Text('Page requests data from ViewModel'),  
            Text('ViewModel requests data from Model'),  
            Text('ViewModel notifies UI updates via notifyListeners'),  
            Text(  
              '${counterViewModel.counter}',  
              style: Theme.of(context).textTheme.headlineMedium,  
            ),  
          ],  
        ),  
      ),  
      floatingActionButton: FloatingActionButton(  
        onPressed: counterViewModel.incrementCounter,  
        tooltip: 'Increment',  
        child: Icon(Icons.add),  
      ),  
    );  
  }  
}  

Key Points:

  • Uses Provider to access the ViewModel.
  • UI elements (e.g., Text, FloatingActionButton) bind to ViewModel properties.

Model.dart

class CounterModel {  
  int _counter = 0;  
  
  int get counter => _counter;  
  
  void increment() {  
    _counter++;  
  }  
}  

Key Points:

  • Encapsulates data (_counter) and business logic (increment()).

MVVM Architecture Analysis

Separation of Concerns

  • Model: Manages data (e.g., _counter) and business rules.
  • View: Focuses solely on UI rendering (e.g., Text, Button).
  • ViewModel: Bridges Model and View, handling data transformations and user interactions.

Data Binding

  • Implemented via ChangeNotifier and Provider.
  • When _counter changes in CounterModel, notifyListeners() triggers UI updates.

Maintainability & Testability

  • Maintainability: Each layer has a clear responsibility.

Testability

:

  • Model can be tested independently.
  • ViewModel can be unit-tested without UI dependencies.

Summary

The MVVM pattern in Flutter (using Provider) achieves:

  1. Decoupling: Separates UI logic from business logic.
  2. Reactivity: Automatic UI updates via data binding.
  3. Scalability: Simplifies complex app architectures.

By leveraging Flutter’s ecosystem, developers can build robust, maintainable apps with clean separation of concerns.