flutter - 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 中的项目实例需要在多个设置(数据表、简单输入等)的多个屏幕上进行访问和更改。例如,项目有一个客户,它有一个客户名称、客户 ID 等,必须从客户设置屏幕进行更改。
我想到了两种方法:
- 创建一个以 ProjectCubit 作为参数并从那里修改项目的 ProjectSettingsCubit、CustomerDataCubit、ProjectDataCubit 等
- 一直使用 ProjectCubit 并从表示层进行更改
实现这一目标的最佳方法是什么?如果整个结构或 Cubit 不好,为什么?
将不胜感激任何帮助,谢谢
解决方案
最佳实践取决于您想要完成的任务。如果您希望您的应用程序在未来扩展,让几个人一起工作,以促进更好的可重用性和更好的可测试性,建议尽可能将业务逻辑和 UI 分开。因此,直接在表示层中有逻辑是没有意义的。当您使用 cubit 时,您会希望在您的程序中保持一致并尝试尽可能多地使 UI 和逻辑解耦。
这当然是有代价的。您需要投入更多时间并使您的代码比以前更复杂。
至于您的答案,我建议您使用 aProjectCubit
并根据您的要求实施几个事件,例如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) {
...
}
}
推荐阅读
- python - 不可见的 tkinter 窗口上的 Blit 图像
- django - 在Django中使用modelchoicefield时如何删除括号和名称?
- hasura - Hasura - 查询标签 - 空数组应该返回所有结果,但只返回带有标签的项目
- mysql - 无法在谷歌云应用引擎上的 laravel 中从 MySQL 加载图片
- javascript - 为整个工作区修复/添加模块导入
- python - 具有不同数据类型的神经网络层
- python - Matplotlib 绘制过多的刻度标签,绘制数据不正确
- javascript - 悬停时的 Fluent-Ui-React 图标轮廓
- python - 根据不同条件对输出值进行分类
- html - 属性 rowspan 使后续元素显示在浏览器的上一行中