Question #69EasyArchitecture

What is MVC ?

#mvc

Answer

Overview

MVC (Model-View-Controller) is one of the most widely used architectural design patterns in software development. It separates an application into three interconnected components, making code more organized, maintainable, and testable.


The Three Components

ComponentRoleResponsibility
ModelData layerHolds business logic, data, and state
ViewUI layerDisplays data; what the user sees
ControllerLogic layerBridges Model and View; handles user input

How It Works

text
User Input → Controller → Model (update data) → View (re-renders)
  1. User interacts with the View (e.g., taps a button)
  2. The View notifies the Controller
  3. The Controller updates the Model
  4. The Model notifies the View to refresh
  5. The View re-renders with new data

MVC in Flutter (Example)

Model

dart
class UserModel {
  String name;
  String email;
  int age;

  UserModel({
    required this.name,
    required this.email,
    required this.age,
  });

  // Business logic lives here
  bool isAdult() => age >= 18;

  // JSON conversion
  factory UserModel.fromJson(Map<String, dynamic> json) {
    return UserModel(
      name: json['name'],
      email: json['email'],
      age: json['age'],
    );
  }
}

Controller

dart
class UserController {
  UserModel? _user;

  UserModel? get user => _user;

  // Fetch user from API
  Future<void> fetchUser(int id) async {
    final response = await ApiService.getUser(id);
    _user = UserModel.fromJson(response);
  }

  // Update user name
  void updateName(String newName) {
    _user?.name = newName;
  }

  bool isUserAdult() => _user?.isAdult() ?? false;
}

View

dart
class UserView extends StatefulWidget {
  
  _UserViewState createState() => _UserViewState();
}

class _UserViewState extends State<UserView> {
  final UserController _controller = UserController();

  
  void initState() {
    super.initState();
    _loadUser();
  }

  Future<void> _loadUser() async {
    await _controller.fetchUser(1);
    setState(() {}); // Re-render with updated data
  }

  
  Widget build(BuildContext context) {
    final user = _controller.user;
    return Scaffold(
      appBar: AppBar(title: Text('MVC Example')),
      body: user == null
          ? CircularProgressIndicator()
          : Column(
              children: [
                Text('Name: ${user.name}'),
                Text('Email: ${user.email}'),
                Text('Adult: ${_controller.isUserAdult()}'),
              ],
            ),
    );
  }
}

Pros and Cons

ProsCons
✅ Clear separation of concerns❌ Controller can become too large ("Massive Controller")
✅ Easy to understand for beginners❌ View and Controller can be tightly coupled
✅ Easy to test Model independently❌ Not ideal for complex Flutter state management
✅ Industry standard pattern❌ Hard to scale in large apps

MVC vs Other Patterns in Flutter

PatternKey Difference
MVCController connects View ↔ Model
MVPPresenter is more decoupled than Controller; View is passive
MVVMViewModel uses data binding; View auto-updates
Clean ArchitectureMultiple layers with strict dependency rules

Note: Pure MVC is not commonly used in Flutter. Most Flutter apps use MVVM (with Provider/Riverpod) or BLoC pattern instead, which work better with Flutter's reactive UI model.