Flutter MVC架构详解:经典架构模式实战

一、MVC概述

MVC(Model-View-Controller)是一种经典的软件架构模式,将应用分为三个主要部分。

1.1 组件职责

组件 职责
Model 数据和业务逻辑
View 用户界面展示
Controller 处理用户交互

二、实现MVC

2.1 Model层

class User {
  final int id;
  final String name;
  final String email;
  
  User({required this.id, required this.name, required this.email});
  
  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'],
      name: json['name'],
      email: json['email'],
    );
  }
  
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'email': email,
    };
  }
}

class UserRepository {
  Future<User> getUser(int id) async {
    // 模拟API调用
    await Future.delayed(const Duration(seconds: 1));
    return User(id: id, name: 'John Doe', email: 'john@example.com');
  }
}

2.2 Controller层

class UserController {
  final UserRepository _repository;
  User? _user;
  bool _isLoading = false;
  String? _error;
  
  UserController(this._repository);
  
  User? get user => _user;
  bool get isLoading => _isLoading;
  String? get error => _error;
  
  Future<void> fetchUser(int id) async {
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      _user = await _repository.getUser(id);
    } catch (e) {
      _error = e.toString();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 通知机制(可以使用ChangeNotifier或自定义)
  void notifyListeners() {}
}

2.3 View层

class UserView extends StatelessWidget {
  final UserController controller;
  
  const UserView({super.key, required this.controller});
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('User Profile')),
      body: controller.isLoading
          ? const Center(child: CircularProgressIndicator())
          : controller.error != null
              ? Center(child: Text('Error: ${controller.error}'))
              : controller.user != null
                  ? UserProfile(user: controller.user!)
                  : const Center(child: Text('No user data')),
    );
  }
}

class UserProfile extends StatelessWidget {
  final User user;
  
  const UserProfile({super.key, required this.user});
  
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        children: [
          const CircleAvatar(radius: 40),
          const SizedBox(height: 16),
          Text(user.name, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
          Text(user.email, style: const TextStyle(color: Colors.grey)),
        ],
      ),
    );
  }
}

三、使用ChangeNotifier

import 'package:flutter/foundation.dart';

class UserController extends ChangeNotifier {
  final UserRepository _repository;
  User? _user;
  bool _isLoading = false;
  String? _error;
  
  UserController(this._repository);
  
  User? get user => _user;
  bool get isLoading => _isLoading;
  String? get error => _error;
  
  Future<void> fetchUser(int id) async {
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      _user = await _repository.getUser(id);
    } catch (e) {
      _error = e.toString();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
}

// 使用
class UserPage extends StatelessWidget {
  const UserPage({super.key});
  
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => UserController(UserRepository()),
      child: const UserView(),
    );
  }
}

class UserView extends Consumer<UserController> {
  const UserView({super.key});
  
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final controller = ref.watch(userControllerProvider);
    
    return Scaffold(
      appBar: AppBar(title: const Text('User')),
      body: controller.isLoading
          ? const CircularProgressIndicator()
          : UserProfile(user: controller.user!),
      floatingActionButton: FloatingActionButton(
        onPressed: () => controller.fetchUser(1),
        child: const Icon(Icons.refresh),
      ),
    );
  }
}

四、项目结构

lib/
  models/
    user.dart
  repositories/
    user_repository.dart
  controllers/
    user_controller.dart
  views/
    user_page.dart
    user_profile.dart
  main.dart

五、MVC与其他架构对比

架构 优点 缺点
MVC 简单直观,职责分明 View和Controller耦合
MVP 解耦View和Model Presenter代码量大
MVVM 数据绑定,可测试性好 学习曲线较陡
Clean Architecture 高度解耦,易维护 结构复杂

总结

MVC是一种经典的架构模式,适合中小型Flutter应用。

关键要点:

  1. Model:数据模型和业务逻辑
  2. View:UI展示,不包含业务逻辑
  3. Controller:处理用户交互,更新Model
  4. ChangeNotifier:实现状态通知机制
  5. Provider:管理Controller生命周期

通过合理使用MVC,你可以构建结构清晰、易于维护的Flutter应用。

更多推荐