felangel / bloc

A predictable state management library that helps implement the BLoC design pattern
https://bloclibrary.dev
MIT License
11.56k stars 3.37k forks source link

question: How do I design the architecture of A very complex desktop app #4131

Closed onism0106 closed 3 months ago

onism0106 commented 3 months ago

Perhaps this is the most complex application currently being developed using the Bloc framework. I'm developing a low-code application where users can drag and drop to create pages and define page data to generate project code. As this is a desktop application, there aren't many pages, or it can be seen as having only one page. It's divided into several modules: Dashboard Module, Page Module, Network Module, Resource Module. So, it definitely cannot have just one Bloc. I've defined a Bloc for each module to manage: DashBloc, PageBloc, NetworkBloc, ResBloc. Here, the dashboard module loads all pages, and the page module is a workspace but can open multiple page tabs simultaneously. Both DashBloc and PageBloc depend on the data layer: PagesRepository. PagesRepository contains the list of all project pages, List pages. PageModel describes a page's components (recorded in a tree structure), data (multiple data lists), and business logic. Taking the page module as an example, it records all opened tab items of the user, List openedTabList. For each open tab, as a pageModel is very complex, I've divided a page into several sub-modules: component module, data module, logic module. Let's not consider the logic module for now. The component module contains a component tree, organizing Widgets in a tree structure. Each Widget has multiple properties. Editing these properties allows previewing the component's style. The data module contains multiple data lists. When I edit a property of a component in a page, the entire PageModel gets refreshed. This leads to the refresh of all open tab pages in the page module. Due to the excessive states, this is not what I expect. I want to create corresponding Blocs for each submodule of each page. For example, the component module could have WidgetBloc, the data module could have DataBloc, and the logic module could have LogicBloc. The states of these three Blocs come from the same page model, PageModel. However, when I need to modify a property of a component in the component module, it should also sync with List pages for saving. Simultaneously, List openedTabList also needs to sync.

jttuboi commented 3 months ago

Hi @onism0106, I’m not a pro in bloc, but I have some experience with this package.

This is not a solution, but it’s the way if I need to implement some complex screens using bloc.

First, I use one bloc to manage the screen. It’s not an obligation, but helps a lot with initial state, loading state, save state, show errors or some attributes that is global for that screen. After, each page (which you use to drag and drop), has its own bloc, because I think these pages have complex controls. For minor widgets, I prefer to use setState or ValueNotifier, because they’re simple to implement, and they don’t depend of any packages.

The main problem of all these is sincronize when they need to talk between them, so you can use other tecnology as observable pattern or event-driven architecture or even a simples plug and play (these are only examples).

Of course it always has better solutions, I’m only show what I know and what possibly I would do it, and I hope it helps with something.

onism0106 commented 3 months ago

Hi @onism0106, I’m not a pro in bloc, but I have some experience with this package.

This is not a solution, but it’s the way if I need to implement some complex screens using bloc.

First, I use one bloc to manage the screen. It’s not an obligation, but helps a lot with initial state, loading state, save state, show errors or some attributes that is global for that screen. After, each page (which you use to drag and drop), has its own bloc, because I think these pages have complex controls. For minor widgets, I prefer to use setState or ValueNotifier, because they’re simple to implement, and they don’t depend of any packages.

The main problem of all these is sincronize when they need to talk between them, so you can use other tecnology as observable pattern or event-driven architecture or even a simples plug and play (these are only examples).

Of course it always has better solutions, I’m only show what I know and what possibly I would do it, and I hope it helps with something.

Hi @jttuboi If each page is managed by its own bloc, but they all share data from the same model, which is quite complex (such as a page model in low-code development), defining page information like name, route, variables, and even the page's component tree (where users can drag and drop components) along with their properties and styles, you might face a design decision:

Should each bloc define its own state, or should they all rely on this huge page model?

felangel commented 3 months ago

Hi @onism0106 👋 Thanks for opening an issue!

I think this type of discussion would potentially be better suited for Discord. Going to close this issue for now since it's hard to provide concrete suggestions without additional information/context. If this is still puzzling you please let us know on Discord and I'm sure either myself or other community members would be more than happy to share their thoughts/opinions, thanks!