Model-View-ViewModel во флаттере

Введение

MVVM расшифровывается как Model-View-ViewModel, это шаблон архитектурного проектирования, который отделяет логику пользовательского интерфейса от бизнес-логики. Основная цель MVVM — упростить тестирование и обслуживание приложения, разделив его компоненты на разные уровни. В этой статье мы обсудим шаблон проектирования MVVM и то, как его можно реализовать во Flutter.

Архитектура МВВМ

Архитектура MVVM состоит из трех основных компонентов: Model, View и ViewModel.

1.Модель

Модель представляет данные приложения. Он отвечает за управление данными приложения, такими как хранение и извлечение данных из базы данных или сервера.

2. Просмотр

Представление представляет собой пользовательский интерфейс приложения. Он отвечает за отображение данных и получение ввода от пользователя. Во Flutter представления реализованы в виде виджетов.

3.ВьюМодель

ViewModel действует как посредник между представлением и моделью. Он отвечает за обработку взаимодействия с пользователем и соответствующее обновление модели. Он также предоставляет данные представлению через привязку данных, поэтому представление может автоматически обновляться при изменении данных.

Реализация MVVM во Flutter

Во Flutter архитектуру MVVM можно реализовать с помощью различных библиотек управления состоянием, таких как Provider, Bloc и MobX. В этой статье мы будем использовать библиотеку Provider для реализации MVVM во Flutter.

Давайте рассмотрим пример реализации MVVM во Flutter с помощью Provider.

Пример: приложение списка задач

Мы создадим простое приложение Todo List, используя архитектуру MVVM. Приложение позволит пользователям добавлять и удалять задачи.

Модель

Наша модель будет простым классом, представляющим задачу.

class Task {
  final String title;
  final String description;
Task({required this.title, required this.description});
}

Вид

Наш вид будет реализован как виджет Flutter. Он отобразит список задач и предоставит форму для добавления новых задач.

class TaskListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Todo List'),
      ),
      body: Consumer<TaskViewModel>(
        builder: (context, viewModel, child) {
          return ListView.builder(
            itemCount: viewModel.taskList.length,
            itemBuilder: (context, index) {
              final task = viewModel.taskList[index];
              return ListTile(
                title: Text(task.title),
                subtitle: Text(task.description),
                trailing: IconButton(
                  icon: Icon(Icons.delete),
                  onPressed: () => viewModel.deleteTask(index),
                ),
              );
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => AddTaskScreen()),
          );
        },
      ),
    );
  }
}

ViewModel

Наша ViewModel будет отвечать за управление состоянием приложения. Он будет содержать список задач и функций для добавления и удаления задач.

class TaskViewModel extends ChangeNotifier {
  List<Task> _taskList = [];
List<Task> get taskList => _taskList;
  void addTask(Task task) {
    _taskList.add(task);
    notifyListeners();
  }
  void deleteTask(int index) {
    _taskList.removeAt(index);
    notifyListeners();
  }
}

Добавление задачи

Чтобы добавить задачу, мы создадим еще один экран и воспользуемся ViewModel, чтобы добавить задачу в модель.

class AddTaskScreen extends StatefulWidget {
  @override
  _AddTaskScreenState createState() => _AddTaskScreenState();
}

class _AddTaskScreenState extends State<AddTaskScreen> {
  final _taskTitleController = TextEditingController();
  final _taskDescriptionController = TextEditingController();

@override
void dispose() {
  _taskTitleController.dispose();
  _taskDescriptionController.dispose();
  super.dispose();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
    title: Text('Add Task'),
    ),
  body: Column(
    children: [
      Padding(
        padding: const EdgeInsets.all(8.0),
          child: TextField(
            controller: _taskTitleController,
            decoration: InputDecoration(
              labelText: 'Title',
            ),
          ),
        ),
    Padding(
    padding: const EdgeInsets.all(8.0),
    child: TextField(
      controller: _taskDescriptionController,
      decoration: InputDecoration(
          labelText: 'Description',
        ),
      ),
    ),
  ElevatedButton(
    child: Text('Add Task'),
    onPressed: () {
        final title = _taskTitleController.text;
        final description = _taskDescriptionController.text;
        final task = Task(title: title, description: description);
        final viewModel =
        Provider.of<TaskViewModel>(context, listen: false);
        viewModel.addTask(task);
        Navigator.pop(context);
    },
    ),
    ],
  ),
);  
}
}

Заключение

В этой статье мы обсудили архитектуру MVVM и то, как ее можно реализовать во Flutter с помощью библиотеки Provider. Мы использовали приложение Todo List в качестве примера, чтобы продемонстрировать, как можно использовать MVVM для отделения бизнес-логики от логики пользовательского интерфейса. С помощью MVVM мы можем писать чистый, поддерживаемый и тестируемый код.