Our natural way of dealing with complexity is to break it into smaller pieces and then put everything back together.
This is a two step process:
- decompose the problem into smaller parts
- compose the small parts to solve the problem
We decompose in smaller parts because they are easier to understand and implement. The smaller parts can be developed in parallel.
The process of decomposition is about assigning responsibilities and giving names. This makes it easy to talk and reason about. Once we identify a responsibility, we can reuse it.
Composition is about combining the small parts together and establishing a relationship between them. We decide the way these pieces communicate, the order in which they execute, and how data flows between them.
We find a system hard to understand even if it is split in smaller parts, if there is a high number of relations between these parts. In order to make a system easier to understand, we need to minimize the number of possible connections between its parts.
Objects are more than state and behavior working together. Objects are things with responsibilities.
In How to create a three layer application with React, I take a to-do list application and split the responsibilities between the following objects :
TodoDataService: responsible for the communication with the server Todo API
UserDataService: responsible for the communication with the server User API.
TodoStore: the domain store for managing to-dos. It is the single source of truth regarding to-dos.
UserStore: the domain store for managing users.
TodoListContainer: the root container component displaying the list of to-dos.
As you can see, when decomposing, I assign responsibilities and give names.
Next, I compose them together in a single function. This is the place where all objects are created and dependencies injected. It is called Composition Root.
For more on applying functional techniques to React take a look at Functional React.
Learn how to apply the Principles of Design Patterns.