Flutter 应用架构详解

文章总体概览信息图

一、架构概述

Flutter 应用架构决定了代码的组织方式和职责划分。良好的架构可以提高代码的可维护性和可测试性。

1.1 架构原则

  • 单一职责 - 每个组件只负责一项功能
  • 关注点分离 - UI、业务逻辑、数据访问分离
  • 可测试性 - 便于单元测试和集成测试
  • 可扩展性 - 易于添加新功能

二、常见架构模式

2.1 MVC (Model-View-Controller)

// Model
class User {
  final String name;
  final String email;
  
  User({required this.name, required this.email});
}

// View
class UserView extends StatelessWidget {
  final User user;
  
  const UserView({super.key, required this.user});
  
  @override
  Widget build(BuildContext context) {
    return Text('${user.name}: ${user.email}');
  }
}

// Controller
class UserController {
  final UserRepository _repository;
  
  UserController(this._repository);
  
  Future<User> getUser(int id) async {
    return await _repository.fetchUser(id);
  }
}

2.2 MVP (Model-View-Presenter)

// View
abstract class UserView {
  void showUser(User user);
  void showError(String message);
}

// Presenter
class UserPresenter {
  final UserView _view;
  final UserRepository _repository;
  
  UserPresenter(this._view, this._repository);
  
  void loadUser(int id) async {
    try {
      final user = await _repository.fetchUser(id);
      _view.showUser(user);
    } catch (e) {
      _view.showError(e.toString());
    }
  }
}

2.3 MVVM (Model-View-ViewModel)

// ViewModel
class UserViewModel extends ChangeNotifier {
  final UserRepository _repository;
  User? _user;
  String? _error;
  
  User? get user => _user;
  String? get error => _error;
  
  UserViewModel(this._repository);
  
  Future<void> loadUser(int id) async {
    try {
      _user = await _repository.fetchUser(id);
      _error = null;
    } catch (e) {
      _error = e.toString();
      _user = null;
    }
    notifyListeners();
  }
}

// View
class UserScreen extends StatelessWidget {
  const UserScreen({super.key});
  
  @override
  Widget build(BuildContext context) {
    return Consumer<UserViewModel>(
      builder: (context, viewModel, child) {
        if (viewModel.error != null) {
          return Text(viewModel.error!);
        }
        if (viewModel.user == null) {
          return const CircularProgressIndicator();
        }
        return UserView(user: viewModel.user!);
      },
    );
  }
}

2.4 Clean Architecture

// 目录结构
lib/
├── presentation/      # UI层
│   ├── screens/
│   ├── widgets/
│   └── viewmodels/
├── domain/           # 领域层
│   ├── entities/
│   ├── repositories/
│   └── usecases/
└── data/            # 数据层
    ├── datasources/
    ├── models/
    └── repositories/

三、状态管理集成

3.1 Provider

class AppProvider extends StatelessWidget {
  const AppProvider({super.key, required this.child});
  
  final Widget child;
  
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => UserViewModel()),
        ChangeNotifierProvider(create: (_) => ThemeProvider()),
      ],
      child: child,
    );
  }
}

3.2 Riverpod

final userProvider = FutureProvider.family<User, int>((ref, id) async {
  final repository = ref.watch(userRepositoryProvider);
  return repository.fetchUser(id);
});

四、实战案例

4.1 完整架构示例

// domain/entities/user.dart
class User {
  final int id;
  final String name;
  
  const User({required this.id, required this.name});
}

// domain/repositories/user_repository.dart
abstract class UserRepository {
  Future<User> fetchUser(int id);
}

// data/repositories/user_repository_impl.dart
class UserRepositoryImpl implements UserRepository {
  final UserDataSource _dataSource;
  
  UserRepositoryImpl(this._dataSource);
  
  @override
  Future<User> fetchUser(int id) async {
    final json = await _dataSource.getUser(id);
    return User(id: json['id'], name: json['name']);
  }
}

// presentation/viewmodels/user_viewmodel.dart
class UserViewModel extends ChangeNotifier {
  final UserRepository _repository;
  User? _user;
  
  UserViewModel(this._repository);
  
  Future<void> loadUser(int id) async {
    _user = await _repository.fetchUser(id);
    notifyListeners();
  }
}

五、总结

选择合适的架构:

  1. 简单应用 - MVC 或直接使用 StatefulWidget
  2. 中型应用 - MVVM + Provider/Riverpod
  3. 大型应用 - Clean Architecture

架构的核心是分离关注点,提高代码质量。

更多推荐