MVC in Flutter
MVC stands for Model-View-Controller, which is a software architectural pattern commonly used in the development of applications. It separates the application logic into three interconnected components:
- Model: The Model represents the data and business logic of the application. It encapsulates the data structures, operations, and rules that govern the behavior of the application. The Model is responsible for data management, validation, and processing. It does not depend on the user interface or the controller.
- View: The View is responsible for the presentation layer of the application. It provides the user interface that the users interact with. The View displays the data from the Model and sends user input or actions to the Controller. In simpler terms, the View focuses on how the data is displayed and how the users can interact with it.
- Controller: The Controller acts as an intermediary between the Model and the View. It handles the user input, updates the Model based on the input or actions, and updates the View to reflect the changes in the Model. The Controller is responsible for the flow of the application, coordinating the communication between the Model and the View. It does not contain any presentation logic.
6.The key idea behind MVC is the separation of concerns. Each component has a distinct role and responsibility:
- The Model manages the data and business logic, ensuring data consistency and integrity.
- The View focuses on the user interface and presentation, providing an intuitive and visually appealing experience.
- The Controller handles the application flow, processing user input and updating the Model and View accordingly.
MVC promotes modular and reusable code. It allows developers to work on different components independently, making the application easier to understand, maintain, and test. Changes in one component do not directly affect the others, as they are loosely coupled through well-defined interfaces.
MVC is widely used in various frameworks and platforms, including web development, desktop applications, and mobile app development. It provides a clear separation of concerns and helps in building scalable and maintainable applications.
Let’s work on a simple scenario of a calculator application where users can add two numbers.
First, create the project file and add the necessary packages. In this example, we won’t need any additional packages.
Step 1: Creating the Model The Model represents the data and business logic of the application. In this example, let’s create a class called CalculatorModel:
class CalculatorModel {
int number1;
int number2;
int result;
CalculatorModel({this.number1 = 0, this.number2 = 0, this.result = 0});
}
Step 2: Creating the View The View represents the user interface of the application. In this example, let’s create a StatefulWidget called CalculatorView:
import 'package:flutter/material.dart';
class CalculatorView extends StatefulWidget {
@override
_CalculatorViewState createState() => _CalculatorViewState();
}
class _CalculatorViewState extends State<CalculatorView> {
TextEditingController number1Controller = TextEditingController();
TextEditingController number2Controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Calculator'),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TextField(
controller: number1Controller,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Number 1',
),
),
TextField(
controller: number2Controller,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Number 2',
),
),
SizedBox(height: 16.0),
ElevatedButton(
onPressed: () {
int number1 = int.tryParse(number1Controller.text) ?? 0;
int number2 = int.tryParse(number2Controller.text) ?? 0;
int result = number1 + number2;
setState(() {
CalculatorModel calculatorModel = CalculatorModel(
number1: number1,
number2: number2,
result: result,
);
_showResultDialog(calculatorModel);
});
},
child: Text('Add'),
),
],
),
),
);
}
void _showResultDialog(CalculatorModel calculatorModel) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Result'),
content: Text(
'Result: ${calculatorModel.result}',
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
);
},
);
}
}
This CalculatorView widget uses Scaffold to create a simple user interface. It includes two TextFields to capture user input for two numbers and a button to perform addition. The _showResultDialog function displays an AlertDialog to show the result.
Step 3: Creating the Controller The Controller provides the application flow control and handles user interactions. In this example, let’s create a class called CalculatorController:
import 'package:your_app/models/calculator_model.dart';
class CalculatorController {
void addNumbers(CalculatorModel model) {
model.result = model.number1 + model.number2;
}
}
The CalculatorController class provides the addNumbers function to perform addition on the numbers stored in theCalculatorModel.
Step 4: Bringing the Application Structure Together Now, let’s bring together the CalculatorView, CalculatorModel, and CalculatorController to create the structure of the application. Add the following code to the main.dart file:
import 'package:flutter/material.dart';
import 'package:your_app/views/calculator_view.dart';
import 'package:your_app/controllers/calculator_controller.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Calculator App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: CalculatorPage(),
);
}
}
class CalculatorPage extends StatelessWidget {
final CalculatorModel model = CalculatorModel();
final CalculatorController controller = CalculatorController();
@override
Widget build(BuildContext context) {
return CalculatorView(
model: model,
controller: controller,
);
}
}
In this structure, the CalculatorView represents the user interface, the CalculatorModel represents the data and business logic, and the CalculatorController handles the user interactions and updates the Model accordingly.
This structure helps in separating the concerns and improving the organization, maintainability, and testability of the code. Each component can be developed and tested independently.
Please note that this example is kept simple for the purpose of providing a basic understanding of MVC. In real-world applications, the structure can be more complex and extensible.