Flutter清洁架构与状态管理插件clean_architecture_with_state_management的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter清洁架构与状态管理插件clean_architecture_with_state_management的使用

概述

clean_architecture_with_state_management 是一个用于Flutter项目的Dart包,提供了一个结合了清洁架构(Clean Architecture)和状态管理(State Management)的模板。该包旨在帮助开发者实现关注点分离,并且提供了多种状态管理方式的集成。

特性

  • 基于清洁架构原则的关注点分离。
  • 状态管理集成以实现流畅的用户界面。
  • 易于定制和扩展。

开始使用

安装

在你的 pubspec.yaml 文件中添加以下依赖:

dev_dependencies:
  clean_architecture_with_state_management:

使用

基本使用示例:

dart run clean_architecture_with_state_management yourFeatureName

文件结构

以下是生成的文件结构示例:

|- features
|  ┌ feature_name/
|  |- data/
|  |    |-data_sources/
|  |    |    |- local/
|  |    |    |    └  feature_name_local_data_source.dart
|  |    |    └ remote/
|  |    |         └  feature_name_remote_data_source.dart
|  |    |- models/
|  |    |    └  feature_model.dart
|  |    └ repositories/
|  |         └  feature_name_repository_impl.dart
|  |- domain/
|  |    |- entities/
|  |    |    └  feature.dart
|  |    |- repositories/
|  |    |    └  feature_repository.dart
|  |    └ use_case/
|  |         └  feature_use_case.dart
|  |- presentation/
|  |    |- widgets/
|  |    └  screens/
|  |         └  feature_screen.dart
|  └ inject_feature_name.dart

创建带Provider的状态管理架构

dart run clean_architecture_with_state_management yourFeatureName -provider

文件结构示例:

|- features
|  ┌ feature_name/
|  |- data/
|  |    |-data_sources/
|  |    |    |- local/
|  |    |    |    └  feature_name_local_data_source.dart
|  |    |    └ remote/
|  |    |         └  feature_name_remote_data_source.dart
|  |    |- models/
|  |    |    └  feature_model.dart
|  |    └ repositories/
|  |         └  feature_name_repository_impl.dart
|  |- domain/
|  |    |- entities/
|  |    |    └  feature.dart
|  |    |- repositories/
|  |    |    └  feature_repository.dart
|  |    └ use_case/
|  |         └  feature_use_case.dart
|  |- presentation/
|  |    |- provider/
|  |    |    └  feature_provider.dart
|  |    |- widgets/
|  |    └  screens/
|  |         └  feature_screen.dart
|  └ inject_feature_name.dart

创建带Bloc的状态管理架构

dart run clean_architecture_with_state_management yourFeatureName -bloc

文件结构示例:

|- features
|  ┌ feature_name/
|  |- data/
|  |    |-data_sources/
|  |    |    |- local/
|  |    |    |    └  feature_name_local_data_source.dart
|  |    |    └ remote/
|  |    |         └  feature_name_remote_data_source.dart
|  |    |- models/
|  |    |    └  feature_model.dart
|  |    └ repositories/
|  |         └  feature_name_repository_impl.dart
|  |- domain/
|  |    |- entities/
|  |    |    └  feature.dart
|  |    |- repositories/
|  |    |    └  feature_repository.dart
|  |    └ use_case/
|  |         └  feature_use_case.dart
|  |- presentation/
|  |    |- bloc/
|  |    |    └  feature_bloc.dart
|  |    |    └  feature_event.dart
|  |    |    └  feature_state.dart
|  |    |- widgets/
|  |    └  screens/
|  |         └  feature_screen.dart
|  └ inject_feature_name.dart

创建带Cubit的状态管理架构

dart run clean_architecture_with_state_management yourFeatureName -cubit

文件结构示例:

|- features
|  ┌ feature_name/
|  |- data/
|  |    |-data_sources/
|  |    |    |- local/
|  |    |    |    └  feature_name_local_data_source.dart
|  |    |    └ remote/
|  |    |         └  feature_name_remote_data_source.dart
|  |    |- models/
|  |    |    └  feature_model.dart
|  |    └ repositories/
|  |         └  feature_name_repository_impl.dart
|  |- domain/
|  |    |- entities/
|  |    |    └  feature.dart
|  |    |- repositories/
|  |    |    └  feature_repository.dart
|  |    └ use_case/
|  |         └  feature_use_case.dart
|  |- presentation/
|  |    |- cubit/
|  |    |    └  feature_cubit.dart
|  |    |    └  feature_state.dart
|  |    |- widgets/
|  |    └  screens/
|  |         └  feature_screen.dart
|  └ inject_feature_name.dart

创建带Riverpod的状态管理架构

dart run clean_architecture_with_state_management yourFeatureName -riverpod

文件结构示例:

|- features
|  ┌ feature_name/
|  |- data/
|  |    |-data_sources/
|  |    |    |- local/
|  |    |    |    └  feature_name_local_data_source.dart
|  |    |    └ remote/
|  |    |         └  feature_name_remote_data_source.dart
|  |    |- models/
|  |    |    └  feature_model.dart
|  |    └ repositories/
|  |         └  feature_name_repository_impl.dart
|  |- domain/
|  |    |- entities/
|  |    |    └  feature.dart
|  |    |- repositories/
|  |    |    └  feature_repository.dart
|  |    └ use_case/
|  |         └  feature_use_case.dart
|  |- presentation/
|  |    |- riverpod/
|  |    |    └  feature_.dart
|  |         └  feature_provider.dart
|  |    |- widgets/
|  |    └  screens/
|  |         └  feature_screen.dart
|  └ inject_feature_name.dart

示例代码

以下是一个简单的示例代码,展示了如何设置和运行一个应用:

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

import 'injection_container.dart';

void main() {
  Future.wait([
    ServiceLocator().setup(),
  ]).then((value) {
    runApp(const ProviderScope(child: MyApp()));
  });
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: Container(),
    );
  }
}

这个示例展示了如何使用Riverpod进行状态管理,并初始化应用程序。你可以根据需要替换 Container() 为实际的UI组件。


更多关于Flutter清洁架构与状态管理插件clean_architecture_with_state_management的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter清洁架构与状态管理插件clean_architecture_with_state_management的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter项目中实现清洁架构(Clean Architecture)与状态管理时,clean_architecture_with_state_management 这样的插件可能提供一个结构化的方式来组织代码。然而,请注意,由于具体的插件实现和API可能会随时间变化,这里我将展示一个基于清洁架构和状态管理原则的基本代码框架,而不是直接使用一个假设的插件。

以下是一个简化的Flutter项目结构,遵循清洁架构的原则,并使用Provider作为状态管理解决方案:

项目结构

my_flutter_app/
├── lib/
│   ├── data/                     # 数据层
│   │   ├── data_sources/         # 数据源接口和实现
│   │   ├── models/               # 数据模型
│   │   └── repositories/         # 仓库层,封装数据访问逻辑
│   ├── domain/                   # 业务逻辑层
│   │   ├── entities/             # 业务实体
│   │   ├── use_cases/            # 用例(业务逻辑)
│   ├── presentation/             # 表示层
│   │   ├── blocs/                # 业务逻辑组件(使用Provider管理状态)
│   │   ├── pages/                # 页面
│   │   ├── widgets/             # 可复用组件
│   ├── main.dart                 # 入口文件
├── pubspec.yaml                 # 项目依赖
└── ...

示例代码

数据层

数据模型 (data/models/user.dart):

class UserModel {
  final String id;
  final String name;

  UserModel({required this.id, required this.name});

  // 从实体转换(如果需要的话)
  factory UserModel.fromEntity(UserEntity entity) {
    return UserModel(id: entity.id, name: entity.name);
  }
}

仓库 (data/repositories/user_repository.dart):

import 'package:dart_collection/dart_collection.dart';
import 'data_sources/user_data_source.dart';
import 'models/user.dart';

class UserRepository {
  final UserDataSource userDataSource;

  UserRepository({required this.userDataSource});

  Future<List<UserModel>> getAllUsers() async {
    List<UserEntity> entities = await userDataSource.getAllUsers();
    return entities.map((e) => UserModel.fromEntity(e)).toList();
  }
}

业务逻辑层

实体 (domain/entities/user.dart):

class UserEntity {
  final String id;
  final String name;

  UserEntity({required this.id, required this.name});
}

用例 (domain/use_cases/get_all_users.dart):

import 'package:dartz/dartz.dart';
import 'entities/user.dart';
import '../repositories/user_repository.dart';

class GetAllUsers {
  final UserRepository userRepository;

  GetAllUsers({required this.userRepository});

  Future<Either<String, List<UserEntity>>> execute() async {
    try {
      List<UserModel> users = await userRepository.getAllUsers();
      return Right(users.map((um) => UserEntity(id: um.id, name: um.name)).toList());
    } catch (e) {
      return Left('Failed to fetch users');
    }
  }
}

表示层

Bloc (presentation/blocs/user_bloc.dart):

import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:dartz/dartz.dart';
import 'domain/entities/user.dart';
import 'domain/use_cases/get_all_users.dart';

part 'user_event.dart';
part 'user_state.dart';

class UserBloc extends Bloc<UserEvent, UserState> {
  final GetAllUsers getAllUsers;

  UserBloc({required this.getAllUsers}) : super(UserInitial());

  @override
  Stream<UserState> mapEventToState(UserEvent event) async* {
    if (event is FetchUsersRequested) {
      yield UserLoading();
      final Either<String, List<UserEntity>> result = await getAllUsers.execute();
      yield result.fold(
        (failureMessage) => UserFailure(message: failureMessage),
        (users) => UserSuccess(users: users),
      );
    }
  }
}

事件和状态 (presentation/blocs/user_event.dartpresentation/blocs/user_state.dart):

// user_event.dart
part of 'user_bloc.dart';

abstract class UserEvent {}

class FetchUsersRequested extends UserEvent {}
// user_state.dart
part of 'user_bloc.dart';

abstract class UserState {}

class UserInitial extends UserState {}

class UserLoading extends UserState {}

class UserSuccess extends UserState {
  final List<UserEntity> users;

  UserSuccess({required this.users});
}

class UserFailure extends UserState {
  final String message;

  UserFailure({required this.message});
}

页面 (presentation/pages/user_list_page.dart):

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'blocs/user_bloc.dart';
import 'widgets/user_item.dart';

class UserListPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('User List')),
      body: BlocProvider<UserBloc>(
        create: (context) => UserBloc(getAllUsers: GetAllUsers(/* initialize dependencies */)),
        child: BlocBuilder<UserBloc, UserState>(
          builder: (context, state) {
            if (state is UserLoading) {
              return CircularProgressIndicator();
            } else if (state is UserSuccess) {
              return ListView.builder(
                itemCount: state.users.length,
                itemBuilder: (context, index) {
                  return UserItem(user: state.users[index]);
                },
              );
            } else if (state is UserFailure) {
              return Text('Error: ${state.message}');
            } else {
              return Container();
            }
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => context.read<UserBloc>().add(FetchUsersRequested()),
        tooltip: 'Fetch Users',
        child: Icon(Icons.refresh),
      ),
    );
  }
}

组件 (presentation/widgets/user_item.dart):

import 'package:flutter/material.dart';
import 'domain/entities/user.dart';

class UserItem extends StatelessWidget {
  final UserEntity user;

  UserItem({required this.user});

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(user.name),
      subtitle: Text(user.id),
    );
  }
}

入口文件

main.dart:

import 'package:flutter/material.dart';
import 'presentation/pages/user_list_page.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Clean Architecture Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: UserListPage(),
    );
  }
}

这个示例展示了一个基本的Flutter项目结构,遵循清洁架构原则,并使用Provider(通过Bloc模式)进行状态管理。你可以根据需要扩展和修改这个结构,以适应你的具体需求。

回到顶部