Flutter 应用架构详解
·
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();
}
}
五、总结
选择合适的架构:
- 简单应用 - MVC 或直接使用 StatefulWidget
- 中型应用 - MVVM + Provider/Riverpod
- 大型应用 - Clean Architecture
架构的核心是分离关注点,提高代码质量。
更多推荐
所有评论(0)