首页 > 解决方案 > Flutter 块架构设计

问题描述

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

我在颤振桌面项目中具有以下结构:

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 等,必须从客户设置屏幕进行更改。

我想到了两种方法:

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

将不胜感激任何帮助,谢谢

标签: flutterdartdesktopbloccubit

解决方案


最佳实践取决于您想要完成的任务。如果您希望您的应用程序在未来扩展,让几个人一起工作,以促进更好的可重用性和更好的可测试性,建议尽可能将业务逻辑和 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) {
    ...
  }
}

推荐阅读