Question

We need to get more much more rigorous about managing state in our business application. The heart of our problem is an object, lets call it an "TaxRefundApplication", that has about 20 properties, but there are literally hundreds of interactions between them. Individual properties can be disabled or hidden based on the value of other properties, they can have default values or forced values pulled from other places, switched on the value of still other properties. Numeric properties can have different limits depending on combinations of other properties. Enumerated properties can have different sets of possible values etc. etc.

There is an implicit structure in this madness. The 20 properties can be arranged as a Directed Acyclic Graph (DAG), with properties like "TypeOfRefund" impacting dozens of downstream nodes, but at least there is no circularity.

My best idea for refactoring all this was to make the DAG explicit, to model a DAGNode class, that would have Rules[] and CandidateValues[]. Any upstream node could insert a Rule or CandidateValue into a downstream one. Any change in these 2 arrays would prompt the DAGNode to execute its priority rule and recalculate it's value. A changed value could flow new Rules and CandidateValues into downstream nodes, and prompt them to recalculate in turn. This has lots of advantages. It simplifies and makes explicit. But it also makes changes reversible. A node can only have one value at a time, but if a forced value is no longer forced, the user entered value would still be in CandidateValues[] and could be reinstated.

Then I came across Redux. Inevitably, folk much cleverer than me have struggled with (nearly?) the same problem, and Redux/Elm/Vuex state engines, with debugging tools, are all there ready to go. But I just can't quite see how my DAG can become a Redux store. In my DAG, a node's Rules and CandidateValues are public. I don't want to write a specific action for modifying each different node, I want them all to be addressable with this same limited interface. So, does my problem map onto the Redux problem-space, or should I persevere on my own?

Was it helpful?

Solution

In a redux model, your actions would be things like INSERT_RULE, INSERT_CANDIDATE_VALUE, DELETE_RULE, and DELETE_CANDIDATE_VALUE, CHANGE_RULE, CHANGE_CANDIDATE_VALUE, with parameters for the new value and some sort of index. Your reducer would then take that action and the previous DAG and return a new DAG.

As you still have to write your own reducer, I'm not sure how much this actually helps you. It's sort of orthogonal to your main problem. But you do get the general benefits of immutability and predictable state transitions, which are not insignificant.

Licensed under: CC-BY-SA with attribution
scroll top