我正在使用 bloc 架构在 flutter 中构建一个应用程序,我真的很喜欢它。
对于我的应用程序,我需要管理数据列表。 4种不同类型。它们具有共同的属性:名称和描述。我本质上需要 4 个列表相同,但当用户点击它们时会发生不同的情况。
共享功能是添加项目(需要用户填写名称和可能的描述)、删除并点击项目以转到更详细的视图,用户可以在其中编辑详细信息(例如,每个实体都不同)有些可能有颜色列表,而另一些则没有)。 对于通用列表,我当前定义了一个肘节和回购协议(这些属性在所有实体之间共享):
class CrudListBloc extends Bloc<CrudListEvent, CrudListState> {
final CrudListRepo repo;
CrudListBloc(this.repo) : super(CrudListEmpty()) {
on<CrudListAdd>(_addItem);
on<CrudListDelete>(_deleteItem);
on<CrudListLoad>(_loadItems);
}
}
abstract class CrudListRepo {
Future<List<CrudListItem>> getAllItems();
Future<String> addItem(String name, String? description);
}
class CrudListItem extends Equatable {
final String id;
final String name;
final String? description;
const CrudListItem({required this.id, required this.name, this.description});
@override
List<Object?> get props => [id, name, description];
}
我想到的方法将允许该块的用户提供一个存储库,该存储库仅获取基础数据的名称、ID 和描述。 crudlistbloc 告诉底层存储库使用提供的名称和描述创建一个新的空元素。然后底层存储库返回 id。进入详细视图后,将传递所点击元素的 id,并且可以从特定实体存储库检索完整对象。
我正在努力解决的问题如下:我们可以轻松地创建一个空元素,给定应用程序中 4 个实体中任何一个的 ID 和名称。因此,我们可以直接将 crudlistrepo 创建的项目写入 T 类型的存储库。但是仅获取所有元素的名称和 ID 可能很容易,也可能很困难,具体取决于底层实现。如果我们要使用 SQL,我们可以只选择名称和 ID,然后就到此为止了。但如果底层数据源是 firebase,我们就必须为名称和 id 创建一个单独的集合并复制它们。
因此我怀疑在加载列表时只获取 T 类型的所有对象是否更合适。相同的数据存储两次感觉不对。我们可以创建 CrudList 类型的 crudlist,在其中对 T 进行绑定以使其具有名称和 id。当 T 非常大时,这可能会增加列表的加载时间,但可以适用于所有数据库并避免重复并使实现更加简单。
您建议采用哪种方法,或者是否有更好的方法我没有完全看到?非常感谢!
我努力思考解决方案,但我对 Bloc 架构还很陌生,需要一些建议来解决这个(我预计很常见)问题。
您的挑战围绕规范化与非规范化的数据库管理决策。
标准化:
反规范化:
最佳方法取决于您的具体要求和可用资源。两种策略都有其优点,而且将相同的数据存储两次也完全没有错误。根据您的应用需求进行选择。