Flutter 块架构设计
Posted
技术标签:
【中文标题】Flutter 块架构设计【英文标题】:Flutter bloc architecture design 【发布时间】:2021-10-22 20:26:24 【问题描述】:这不是关于具体实施,而是更多关于良好实践。
我在一个flutter桌面项目中有如下结构:
DataProviders:从两种不同文件格式之一读取数据(本地) 存储库:解析数据并实例化我的模型 ProjectCubit:从 FilePicker 获取路径并从上 2 层获取项目ProjectCubit.dart:
class ProjectCubit extends Cubit<ProjectState>
ProjectCubit() : super(ProjectState.Closed);
Project? loadedProject;
Project? getProject()
// return loaded instance of Project if loaded
if(loadedProject != null)
return loadedProject;
// creates Project instance from csv file
void importProject(String filePath) async
emit(ProjectState.Importing);
loadedProject = await ProjectRepository().loadData(loadType: ProjectLoadType.IMPORT_FROM_CSV, filePath: filePath);
emit(ProjectState.Open);
// open json-Project file
void openProject(String filePath) async
emit(ProjectState.Opening);
try
loadedProject = await ProjectRepository().loadData(loadType: ProjectLoadType.OPEN_PROJECT_FILE, filePath: filePath);
catch (e)
emit(ProjectState.Closed);
Log().l.e("Opening file failed with $e.toString()");
emit(ProjectState.Open);
状态在哪里:
enum ProjectState
Closed,
Importing,
Opening,
Open
ProjectCubit 中的项目实例需要在多个设置(数据表、简单输入等)的多个屏幕上进行访问和更改。例如,Project 有一个 Customer,它有一个 customerName、customerId 等,必须从 Customer-Settings 屏幕进行更改。
我想到了两种方法:
创建一个 ProjectSettingsCubit、CustomerDataCubit、ProjectDataCubit 等,它们将 ProjectCubit 作为参数并从那里修改项目 一直使用 ProjectCubit 并从表示层进行更改实现这一目标的最佳方法是什么?如果整个结构或 Cubit 不好,为什么?
不胜感激,谢谢
【问题讨论】:
【参考方案1】:最佳做法取决于您想要完成的任务。 如果您希望您的应用程序在未来扩展,让几个人一起工作,以促进更好的可重用性和更好的可测试性,建议尽可能将业务逻辑和 UI 分开。因此,直接在表示层中有逻辑是没有意义的。当您使用 cubit 时,您会希望在您的程序中保持一致并尽可能地让 UI 和逻辑解耦。
这当然是有代价的。您需要投入更多时间并使您的代码比以前更复杂。
至于您的答案,我建议使用ProjectCubit
并根据您的要求实施几个事件,例如CustomerChangeEvent
用于更改客户。
如果您有任何特殊要求需要在两个页面中以不同方式实现,那么我建议从基类继承或仅使用 mixin 并将该类扩展为不同的 cubits。
class BaseProjectCubit extends Cubit<ProjectState>
void importProject(String filePath) async
emit(ProjectState.Importing);
loadedProject = await ProjectRepository().loadData(loadType:
ProjectLoadType.IMPORT_FROM_CSV, filePath: filePath);
emit(ProjectState.Open);
...
class ProjectCubitA extends BaseProjectCubit
@override
void importProject(String filePath) async
...
class ProjectCubitB extends BaseProjectCubit
importProject(String filePath) async
...
或者对于使用 mixins,它会是这样的:
mixin ProjectModifier
void importProject(String filePath) async
emit(ProjectState.Importing);
loadedProject = await ProjectRepository().loadData(loadType:
ProjectLoadType.IMPORT_FROM_CSV, filePath: filePath);
emit(ProjectState.Open);
...
class CustomerTypeOneProjectCubit extends Cubit<ProjectState> with ProjectModifier
changeName(String newName)
...
class CustomerTypeTwoProjectCubit extends Cubit<ProjectState> with ProjectModifier
changeName(String newName)
...
【讨论】:
非常感谢,但是,如果我使用 mixin 或 Baseclass 子类模型,我将如何让它们共享同一个 Project 实例?现在我基本上调用 openProject() 一次,并且需要为其他肘的所有操作创建的实例。 我刚刚创建了一个 ProjectSettingsCubitprojectCubit
本身。
我真的很困惑,因为我认为它会按值传递,而不是按引用传递,并且在使用 Project 而不是 ProjectCubit 时我只会编辑一个副本,但它似乎工作,得看看Dart 如何再次传递变量以上是关于Flutter 块架构设计的主要内容,如果未能解决你的问题,请参考以下文章