颤振块结构设计



这不是关于具体的实现,而是关于良好的实践。

我在一个flutter桌面项目中有以下结构:

  • DataProviders:从两种不同的文件格式之一(本地)读取数据
  • Repository:解析数据并实例化我的模型
  • projectcube:从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
}

projectcube中的Project实例需要在多个设置(DataTable,简单输入等)中的多个屏幕中进行访问和更改。例如,项目有一个客户,它有一个customerName, customerId等,必须从客户设置屏幕更改。

我想到了两种方法:

  • 创建ProjectSettingsCubit, CustomerDataCubit, ProjectDataCubit等,将ProjectCubit作为参数并从那里修改项目
  • 一直使用projectcube,并从表示层进行更改

实现这一目标的最佳方法是什么?如果整个结构或Cubit不好,为什么?

感谢任何帮助,谢谢

最佳实践取决于您想要完成什么。如果你想让你的应用在未来扩展,让几个人一起工作,促进更好的可重用性和更好的可测试性,建议将业务逻辑分开。尽可能多地使用UI。因此,直接在表示层中使用逻辑是没有意义的。当您使用cubit时,您会希望在程序中保持一致。尽量让UI和逻辑解耦。

当然,这是有代价的。你需要投入更多的时间。让你的代码比以前更复杂。

关于你的答案,我建议使用ProjectCubit并根据你的要求实施几个事件,如CustomerChangeEvent用于改变客户。

如果你有任何特殊的需求,需要在两个页面中以不同的方式实现,那么我建议从一个基类继承,或者只是使用mixin并在不同的腕尺中扩展那个类。

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) {
...
}
}

最新更新