Комментарии 15
Мне кажется что пример со счетчиком не иллюстрирует каких либо преимуществ использования архитектуры в силу своей простоты. Какой то пример посложнее нужно для демонстрации архитектурного подхода.
Согласны, архитектуру в флаттере можно рассмотреть на примере многих приложений, как простых, так и более сложных. Руководство при этом может превратиться в настоящую книгу) Однако, наша основная задача заключалась в том, чтобы познакомить новичков с реализацией чистой архитектуры на практике. А какие приложения выбрали бы вы?
Хорошо бы в примере было два взаимодействующих домена, иначе не очевидна польза от такого бойлерплейта, особенно, в сравнении с Provider.
Пример с counter вообще подходит лишь для StatefulWidget и setState(), а другие подходы на этом примере лишь выглядят как бессмысленное усложнение.
Официальный пример для Provider на примере корзины решает задачу демонстрации удобства и преимущества предложенного подхода.
Если вы понимаете кейс, в котором cubit даст ощутимую пользу, опишите его.
Иначе, подобные статьи бесполезны и лишь сбивают с толку ищущих толковое объяснение.
Да хотя бы пример с корзиной, дополненный объяснением смысла и пользы использования bloc\cubit уже может быть полезным.
мне вот интересно, на cubit'ах вообще можно что нибудь более менее сложное сделать? Ну например. мне надо загрузить что-то из Интернета, мне должно прилететь два состояния, одно что началась загрузка, другое загруженное с нужными данными. в одном emit'е это сделать нельзя. в таких случаях как раз и надо использовать полноценный Bloc ?
Можно вызывать emit сколько угодно раз, при вызове метода из кубита первым действием уведомить UI, вызвав emit(LoadingState()), загрузить данные из интернета, после emit(LoadedState()).
а как правильно объединять useCase
в цепочку?
а что лучше: в слое domain описывать интерфейс для use_case или для repository? не правильней ли в domain создать интерфейс repository, а в data слое уже repository_impl?
и разве use_case не должен делать что-то одно (либо получить данные, либо сохранить)?
use_case может как получать, так и сохранять данные. Что касается описания интерфейса, предложенный вами способ тоже выглядит логичным, при этом в примере мы для удобства выбрали другой способ - держать абстракцию и реализацию рядом друг с другом.
не увидел сразу. у вас получается в data слое есть так же описание интерфейс для репозитория и там же его реализация. а зачем тогда делать описание интерфейса для use_case если он по факту зависит от интерфейса репозитория? т.е. мы в конструктор usa_case можем передать репозиторий к примеру CounterRepositoryImpl, CounterTestRepositoryImpl, CounterApiRepositoryImpl , CounterHiveRepositoryImpl и т.д.
а методах usa_case уже вызывать методы переданного репозитория, как это у вас и реализовано.
Хорошо бы еще не путать понятия DI и паттерн Service Locator (который на самом деле используется в данном примере)
Спасибо, очень полезно.
Please don't use a cubit. The main reason for using a BLoC is scheduling and protecting against race conditions. Using a cubit is no different from using a change notifier, stream controller, or something like that (except for observer and error handling).
https://plugfox.dev/business-logic-component-3/
Реализуем чистую архитектуру на Flutter с cubit