Docs: provide examples regarding stateful encapsulation and "Good Action Hygiene" #3090
-
I was watching the talk on Good Action Hygiene @MikeRyanDev gave at ngConf and it led me to a few obvious questions that I don't think are well documented or described by existing documentation. ExampleTo illustrate some of these questions, I propose the following example:
In order to keep "Good Action Hygiene", theoretically my sidebar reducer has to be aware of two unique state changes:
Attempting to keep "Good Action Hygiene" when my sidebar "dumb" component starts to become reused in multiple instances across various aspects of the application is hard and creates the following two problems: Difficult/Impossible Stateful Code ReuseReusing state, actions, reducers, selectors, and effects of a given feature is not described well currently and at the moment seems difficult and pretty much impossible whilst maintaining "Good Action Hygiene". Poor EncapsulationThe more major issue in this scenario is poor encapsulation and violation of the "Open/Closed" Principle. In the above example I see the following issues:
Potential SolutionsI see three approaches here:
Personally, I dislike all three of those which makes me uncertain about what the best approach is here; thus the desire for documentation. Do you happen to have a recommendation, pattern or documentation to remediate the above? Additional CommentsPackaging Stateful ComponentsThis conceptual issue, the lack of pattern, and the lack of documentation make writing modularized features that use @ngrx/store (think npm packages) really hard to reason about. As I understand it, I would never be able to publish a stateful package because it would be useless to any consumers since they can't add their own actions to the reducers of the system, as it would violate "Good Action Hygiene". Robustness Principle ConsiderationsThe idea of actions is very much like HTTP or any kind of messaging protocol. Which leads us basically back to the idea of contravariance and covariance and the Robustness Principle, so these should probably be taken into consideration. PolymorphismIn the talk, there's even an argument against subtyping, which throws out the concept of polymorphic actions, so there's even more pain point there, and probably should be documented. I would be willing to submit a PR for the docs ❤️[x] Yes (Assistance is provided if you need help submitting a pull request) Final NotesAccording to @timdeschryver this may well be covered by this article, yet even @timdeschryver admits this problem is hard and that:
So I think this issue is worth addressing. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
As this got bumped, I figured I would revitalize this conversation with some additional learnings and commentary on how we've addressed this in Daffodil(the original reason for this question). Of interest to those curious about solving this problem may be this PR (which references a .drawio file, but I'll add a picture to the PR as well). In short, there's a documentation weakness that I see in To clarify, the sidebar problem can be fixed by:
What this means may be different for every package, but the pattern is useful. Although, I will be the first to say that this pattern has drawbacks:
But, the benefits far outweigh the costs IMHO:
As a final commentary, composing packages together has always been one of the most important aspects of building well-architected software. Without it, software becomes heavy, unwieldy, and monolithic. With it, software becomes wiry and complicated: See You have to drink poison, regardless of which you choose. @alex-okrushko and I had a discussion on this topic a year or so back, and DI'd reducers were advised against, Since that, I've seen @alex-okrushko dislike meta-reducers as well. IMHO I think it's a choice that one has to make. For most, DI'd reducers and meta-reducers are overkill and confusing. Yet, for the select few they are quite the useful hammer. |
Beta Was this translation helpful? Give feedback.
As this got bumped, I figured I would revitalize this conversation with some additional learnings and commentary on how we've addressed this in Daffodil(the original reason for this question).
Of interest to those curious about solving this problem may be this PR (which references a .drawio file, but I'll add a picture to the PR as well).
In short, there's a documentation weakness that I see in
@ngrx/store
today: using dependency injected reducers.To clarify, the sidebar problem can be fixed by:
state
API (much like entity adapter does)