Flutter如何实现clean架构

“在Flutter中实现Clean架构时,应该如何正确划分数据层、领域层和表现层?求具体代码示例和最佳实践,特别是跨层交互和依赖注入的处理方式。”

2 回复

Flutter实现Clean架构可通过分层:

  1. 领域层:实体与业务逻辑。
  2. 数据层:仓库实现,数据源(本地/远程)。
  3. 表示层:UI(页面、组件)与状态管理(如Bloc、Provider)。
    各层依赖单向流动,确保低耦合、易测试。

更多关于Flutter如何实现clean架构的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现Clean Architecture,可以按照以下结构组织项目:

项目结构

lib/
├── core/           # 通用工具和常量
├── features/       # 功能模块
│   └── user/
│       ├── data/           # 数据层
│       │   ├── datasources/    # 数据源接口和实现
│       │   ├── models/         # 数据模型
│       │   └── repositories/   # 仓库实现
│       ├── domain/         # 领域层
│       │   ├── entities/       # 业务实体
│       │   ├── repositories/   # 仓库接口
│       │   └── usecases/       # 用例
│       └── presentation/   # 表现层
│           ├── pages/          # 页面
│           ├── widgets/        # 组件
│           └── providers/      # 状态管理
└── injection.dart    # 依赖注入

核心实现

1. 领域层(Domain)

// entities/user_entity.dart
class UserEntity {
  final String id;
  final String name;
  final String email;
  
  UserEntity({required this.id, required this.name, required this.email});
}

// repositories/user_repository.dart
abstract class UserRepository {
  Future<UserEntity> getUser(String id);
  Future<void> saveUser(UserEntity user);
}

// usecases/get_user_usecase.dart
class GetUserUseCase {
  final UserRepository repository;
  
  GetUserUseCase(this.repository);
  
  Future<UserEntity> execute(String id) {
    return repository.getUser(id);
  }
}

2. 数据层(Data)

// models/user_model.dart
class UserModel extends UserEntity {
  UserModel({required String id, required String name, required String email})
      : super(id: id, name: name, email: email);
  
  factory UserModel.fromJson(Map<String, dynamic> json) {
    return UserModel(
      id: json['id'],
      name: json['name'],
      email: json['email'],
    );
  }
}

// datasources/user_remote_data_source.dart
abstract class UserRemoteDataSource {
  Future<UserModel> getUser(String id);
}

// repositories/user_repository_impl.dart
class UserRepositoryImpl implements UserRepository {
  final UserRemoteDataSource remoteDataSource;
  
  UserRepositoryImpl(this.remoteDataSource);
  
  @override
  Future<UserEntity> getUser(String id) async {
    final userModel = await remoteDataSource.getUser(id);
    return userModel; // 自动向上转型为UserEntity
  }
}

3. 表现层(Presentation)

// providers/user_provider.dart
class UserProvider with ChangeNotifier {
  final GetUserUseCase getUserUseCase;
  UserEntity? _user;
  
  UserProvider(this.getUserUseCase);
  
  UserEntity? get user => _user;
  
  Future<void> fetchUser(String id) async {
    _user = await getUserUseCase.execute(id);
    notifyListeners();
  }
}

// pages/user_page.dart
class UserPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => UserProvider(
        GetUserUseCase(
          UserRepositoryImpl(
            UserRemoteDataSourceImpl(),
          ),
        ),
      ),
      child: Consumer<UserProvider>(
        builder: (context, provider, child) {
          if (provider.user == null) {
            return CircularProgressIndicator();
          }
          return Text('User: ${provider.user!.name}');
        },
      ),
    );
  }
}

依赖注入

使用get_it或provider进行依赖注入:

// injection.dart
final getIt = GetIt.instance;

void setup() {
  getIt.registerFactory(() => UserRemoteDataSourceImpl());
  getIt.registerFactory(() => UserRepositoryImpl(getIt()));
  getIt.registerFactory(() => GetUserUseCase(getIt()));
}

核心原则

  1. 依赖规则:内层不依赖外层,依赖方向从外向内
  2. 单一职责:每个类/层有明确职责
  3. 接口隔离:通过抽象接口进行层间通信
  4. 测试友好:易于单元测试和模拟

这种架构确保了代码的可维护性、可测试性和可扩展性。

回到顶部