Riverpod 的 Flutter 项目目录结构最佳实践

0

1. 基础项目结构

lib/
├── main.dart
├── app/
│   ├── app.dart
│   ├── router/
│   └── theme/
├── core/
│   ├── constants/
│   ├── exceptions/
│   ├── extensions/
│   ├── utils/
│   └── network/
├── features/
│   ├── auth/
│   ├── home/
│   ├── profile/
│   └── settings/
├── shared/
│   ├── providers/
│   ├── widgets/
│   ├── models/
│   └── services/
└── generated/

2. 详细目录结构

核心应用层

app/
├── app.dart                    # 主应用配置
├── router/
│   ├── app_router.dart         # 路由配置
│   ├── router_provider.dart    # 路由相关 Provider
│   └── routes.dart             # 路由常量
└── theme/
    ├── app_theme.dart          # 主题配置
    └── theme_provider.dart     # 主题 Provider

核心功能层

core/
├── constants/
│   ├── api_constants.dart
│   ├── app_constants.dart
│   └── storage_keys.dart
├── exceptions/
│   ├── app_exception.dart
│   ├── network_exception.dart
│   └── cache_exception.dart
├── extensions/
│   ├── string_extension.dart
│   ├── context_extension.dart
│   └── date_extension.dart
├── utils/
│   ├── logger.dart
│   ├── validators.dart
│   └── formatters.dart
└── network/
    ├── dio_client.dart
    ├── api_client.dart
    └── network_provider.dart

3. 功能模块结构(Feature-First)

每个功能模块采用完整的分层结构:

features/
├── auth/
│   ├── data/
│   │   ├── datasources/
│   │   │   ├── auth_local_datasource.dart
│   │   │   └── auth_remote_datasource.dart
│   │   ├── models/
│   │   │   ├── login_request.dart
│   │   │   ├── login_response.dart
│   │   │   └── user_model.dart
│   │   ├── repositories/
│   │   │   └── auth_repository_impl.dart
│   │   └── providers/
│   │       └── auth_data_providers.dart
│   ├── domain/
│   │   ├── entities/
│   │   │   └── user_entity.dart
│   │   ├── repositories/
│   │   │   └── auth_repository.dart
│   │   ├── usecases/
│   │   │   ├── login_usecase.dart
│   │   │   ├── logout_usecase.dart
│   │   │   └── get_current_user_usecase.dart
│   │   └── providers/
│   │       └── auth_domain_providers.dart
│   └── presentation/
│       ├── providers/
│       │   ├── auth_state_provider.dart
│       │   ├── login_form_provider.dart
│       │   └── auth_notifier.dart
│       ├── pages/
│       │   ├── login_page.dart
│       │   ├── register_page.dart
│       │   └── forgot_password_page.dart
│       ├── widgets/
│       │   ├── login_form.dart
│       │   ├── auth_button.dart
│       │   └── password_field.dart
│       └── state/
│           ├── auth_state.dart
│           └── login_form_state.dart
├── home/
│   └── ... (类似结构)
└── profile/
    └── ... (类似结构)

4. 共享资源结构

shared/
├── providers/
│   ├── app_providers.dart          # 全局应用 Provider
│   ├── storage_providers.dart      # 存储相关 Provider
│   ├── connectivity_providers.dart # 网络连接 Provider
│   └── device_info_providers.dart  # 设备信息 Provider
├── widgets/
│   ├── common/
│   │   ├── custom_button.dart
│   │   ├── loading_widget.dart
│   │   ├── error_widget.dart
│   │   └── empty_state_widget.dart
│   ├── forms/
│   │   ├── custom_text_field.dart
│   │   ├── custom_dropdown.dart
│   │   └── form_validators.dart
│   └── layouts/
│       ├── scaffold_with_nav.dart
│       └── responsive_layout.dart
├── models/
│   ├── api_response.dart
│   ├── pagination.dart
│   └── result.dart
└── services/
    ├── storage_service.dart
    ├── notification_service.dart
    ├── analytics_service.dart
    └── cache_service.dart

5. Provider 组织最佳实践

全局 Provider 集中管理

// shared/providers/app_providers.dart
import 'package:riverpod/riverpod.dart';

// 基础服务 Provider
final storageServiceProvider = Provider<StorageService>((ref) {
  return StorageService();
});

final apiClientProvider = Provider<ApiClient>((ref) {
  return ApiClient();
});

final loggerProvider = Provider<Logger>((ref) {
  return Logger();
});

// 应用级状态 Provider
final connectivityProvider = StreamProvider<ConnectivityResult>((ref) {
  return Connectivity().onConnectivityChanged;
});

final deviceInfoProvider = FutureProvider<DeviceInfo>((ref) async {
  return await DeviceInfoService.getDeviceInfo();
});

功能模块 Provider 分层

// features/auth/data/providers/auth_data_providers.dart
final authLocalDataSourceProvider = Provider<AuthLocalDataSource>((ref) {
  final storage = ref.read(storageServiceProvider);
  return AuthLocalDataSource(storage);
});

final authRemoteDataSourceProvider = Provider<AuthRemoteDataSource>((ref) {
  final client = ref.read(apiClientProvider);
  return AuthRemoteDataSource(client);
});

final authRepositoryProvider = Provider<AuthRepository>((ref) {
  final localDS = ref.read(authLocalDataSourceProvider);
  final remoteDS = ref.read(authRemoteDataSourceProvider);
  return AuthRepositoryImpl(localDS, remoteDS);
});

// features/auth/domain/providers/auth_domain_providers.dart
final loginUseCaseProvider = Provider<LoginUseCase>((ref) {
  final repository = ref.read(authRepositoryProvider);
  return LoginUseCase(repository);
});

final getCurrentUserUseCaseProvider = Provider<GetCurrentUserUseCase>((ref) {
  final repository = ref.read(authRepositoryProvider);
  return GetCurrentUserUseCase(repository);
});

// features/auth/presentation/providers/auth_state_provider.dart
final authStateProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
  final loginUseCase = ref.read(loginUseCaseProvider);
  final getCurrentUserUseCase = ref.read(getCurrentUserUseCaseProvider);
  return AuthNotifier(loginUseCase, getCurrentUserUseCase);
});

6. 文件命名约定

命名规则:
- Provider 文件:{feature}_providers.dart
- State 类:{Feature}State
- Notifier 类:{Feature}Notifier
- UseCase 类:{Action}UseCase
- Repository 实现:{Feature}RepositoryImpl
- Model 类:{Feature}Model
- Entity 类:{Feature}Entity
- Page 组件:{Feature}Page
- Widget 组件:{Feature}Widget

7. 导入组织

// features/auth/presentation/pages/login_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

// 核心导入
import '../../../../core/extensions/context_extension.dart';
import '../../../../shared/widgets/common/custom_button.dart';

// 功能模块导入
import '../providers/auth_state_provider.dart';
import '../widgets/login_form.dart';
import '../state/auth_state.dart';

8. 测试目录结构

test/
├── features/
│   ├── auth/
│   │   ├── data/
│   │   │   ├── datasources/
│   │   │   ├── models/
│   │   │   └── repositories/
│   │   ├── domain/
│   │   │   ├── usecases/
│   │   │   └── repositories/
│   │   └── presentation/
│   │       ├── providers/
│   │       └── pages/
│   └── ...
├── shared/
│   ├── services/
│   └── widgets/
├── helpers/
│   ├── test_helpers.dart
│   └── mock_providers.dart
└── fixtures/
    └── auth_fixtures.dart

9. 配置文件结构

lib/
├── config/
│   ├── app_config.dart
│   ├── env_config.dart
│   └── flavor_config.dart
└── environment/
    ├── dev_config.dart
    ├── staging_config.dart
    └── prod_config.dart

10. 完整的 main.dart 示例

// lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'app/app.dart';
import 'core/utils/logger.dart';
import 'shared/providers/app_providers.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化日志
  Logger.init();
  
  runApp(
    ProviderScope(
      observers: [AppProviderObserver()],
      child: const MyApp(),
    ),
  );
}

class AppProviderObserver extends ProviderObserver {
  @override
  void didUpdateProvider(
    ProviderBase provider,
    Object? previousValue,
    Object? newValue,
    ProviderContainer container,
  ) {
    Logger.d('Provider updated: ${provider.name ?? provider.runtimeType}');
  }
}

这种目录结构的优势:

  • 清晰的分离: 功能模块独立,依赖关系明确

  • 可扩展性: 易于添加新功能模块

  • 可测试性: 每层都可以独立测试

  • 可维护性: 代码组织清晰,便于维护

  • 团队协作: 不同开发者可以专注不同模块