我是Flutter的新手,刚刚从阅读有关Flutter的教程中听到了BLoC概念。通过此tutorial,我第一次听到了BLoC。但是我在本文中还看到了一个名为“存储库”的文件。基本上,数据流是这样的:
Web API --> Api Provider --> Repository --> BLoC --> Widget
我不明白的是,为什么需要存储库层,当我查看存储库文件时,它基本上只是返回API Provider的Future结果?我很好奇,并尝试进一步搜索,我看到互联网上某些人的编码模式也有一个存储库层。
在原始文章中,API Provider做所有事情。它将调用get请求,等待Future解析,它将JSON数据转换为适当的模型,然后返回Future随附的模型。
class ApiProvider {
Future<ItemModel> fetchMovieList() async {
final response = await client.get("http://api.themoviedb.org/3/movie/popular?api_key=$_apiKey");
if (response.statusCode == 200)
return ItemModel.fromJson(json.decode(response.body));
else
throw Exception('Failed to load post');
}
}
class Repository {
ApiProvider _api = ApiProvider();
Future<ItemModel> fetchMovieList() => _api.fetchMovieList(); // why?
}
class Bloc {
Repository _repository = Repository();
final _moviesFetcher = PublishSubject<ItemModel>();
Observable<ItemModel> get allMovies => _moviesFetcher.stream;
fetchAllMovies() async {
ItemModel itemModel = await
_repository.fetchAllMovies();
_moviesFetcher.sink.add(itemModel);
}
}
当前,我对其进行了修改,以使Api Provider返回纯Future,其中存储库实现.then()
并将响应转换为适当的数据,但是我倾向于避免等待,因为在React Native中,等待导致应用程序看起来没有反应。我还将错误检查移至BLoC。
class ApiProvider {
Future fetchMovieList() => client.get("http://api.themoviedb.org/3/movie/popular?api_key=$_apiKey");
}
class Repository {
ApiProvider _api = ApiProvider();
Future<ItemModel> fetchMovieList() => _api.fetchMovieList().then(response => ItemModel.fromJson(json.decode(response.body));
}
class Bloc {
Repository _repository = Repository();
final _moviesFetcher = PublishSubject<ItemModel>();
Observable<ItemModel> get allMovies => _moviesFetcher.stream;
fetchAllMovies() async => _repository.fetchPopularMovies().then((response) => _moviesFetcher.sink.add(response))
.catchError((onError) => throw Exception("Failed to load post $onError"));
}
但是,我仍然觉得这足以证明需要此存储库层。如果可以的话,我想这样:
class ApiProvider {
Future<ItemModel> fetchMovieList() => client.get("http://api.themoviedb.org/3/movie/popular?api_key=$_apiKey")
.then(response => ItemModel.fromJson(json.decode(response.body));
}
class Bloc {
ApiProvider _api = ApiProvider();
final _moviesFetcher = PublishSubject<ItemModel>();
Observable<ItemModel> get allMovies => _moviesFetcher.stream;
fetchAllMovies() async => _api.fetchPopularMovies().then((response) => _moviesFetcher.sink.add(response))
.catchError((onError) => throw Exception("Failed to load post $onError"));
}
并完全摆脱存储库层。我并不是要说“存储库”层是不必要的,但是现在我不知道“存储库”层试图解决什么模式问题。我只是想知道为什么首先要有一个Repository层,以及现实世界中Repository的重要用例是什么。我知道这个问题可能被标记为可以引发讨论而不是直接回答的问题。但是我相信这个问题会有一些狭窄的答案。尝试在Internet上搜索时,我只是找不到它(搜索结果与git和subversion之类的“存储库”术语的其他用法混合在一起。)
答案 0 :(得分:0)
好吧,算了吧。我发现这个excellent article可以解释说,基本上,存储库是抽象数据的来源,无论是来自磁盘缓存,云还是其他来源。工厂将根据每个来源的可用性来决定使用哪个来源。呼叫者只需要经过一个门。因为上面的教程只有一个来源(API /云),所以对我而言这似乎毫无用处。