slorber / scalable-frontend-with-elm-or-redux

An attempt to make Redux and Elm applications scale
http://sebastienlorber.com/
MIT License
361 stars 29 forks source link

Solution feedback: redux-elm-tomkis1 #19

Open tomkis opened 8 years ago

tomkis commented 8 years ago

The 3 components (NewGif/Counter/Button) should be decoupled and not see each others in any way. They can't import stuff from each others. Ideally, in a JS based solutions, one could be able to publish each 3 components in separate NPM packages that don't depend on each others.

This is currently possible because Components only expose public interface

The aim of decoupling the components is that a team can take ownership of each component. Then another team is responsible of making all the components work nicely together, and you already have split the work into 4 teams.

I actually worked like this, I've built 3 independent components which are isolated:

  1. GifViewer
  2. Button
  3. Counter

I just kept in mind the public interface which is necessary to implement the business rule. That's why:

  1. Button exposes isActive function
  2. Counter exposes incrementByTwo and increment functions

So that all the component specific logic is encapsulated.

The business rule then looks like this:

  .case('NewGif', function*(model, action) {
    return {
      ...model,
      counter: ButtonApi.isActive(model.button) ?
        CounterApi.incrementByTwo(model.counter) :
        CounterApi.increment(model.counter)
    };
  }, endsWithMatcher)

I've utilized Custom Matcher implementation (redux-elm allows you to build your own Matcher) to fetch all NewGif actions. If I wanted to keep it formally correct, I'd expose the Action string from GifViewer component so that I don't need to know internal details of GifViewer (I didn't do that tho, using just string)

For example, the NewGif component should not be aware of the presence of the existence of a counter, deeply hidden in a little stats popup of our app. If this counter had to be removed by the business, it's place in dom tree updated, or it's business rule be changed, the team maintaining the NewGif widget should rather not have to know about that.

Each component does not know anything about their parent. Didn't need to change single line of code in GifViewer to implement the business rule.

It should also be easy to move the position of components. For example imagine the button is top left of your app, and the business now wants it inside a popup, bottom right: this move of component in the tree should rather be easy to make (ie without having to modify all parent components, for example).

endsWithMatcher does the magic, I can move around components however I want, yet everything will still be working.

tomkis commented 8 years ago

Using next version of https://github.com/salsita/redux-elm/tree/next