It doesn't leak to the rest of the system. Compare that to this button component. One could argue that it doesn't do much compared to the complexity of its interface. More importantly, we can see that it's mixing several concerns here. We have the concerns of the button itself, but we also have the concerns of the icon and the tooltip. So not only the implementation of this component is likely very complex, but it's also spreading that complexity through the rest of the codebase.
It's important to know that nobody sets out to build something very complex from the start. Things usually start simple, like our initial implementation of the location card. This was a powerful component with a simple interface. It was a deep module, until it wasn't. So it's important that we control this evolution to make sure that the abstractions we implemented in the beginning are still the right solutions to the problems that we have today.
And this brings me to my final technique for managing complexity, which is aiming your efforts at reducing cognitive load. By this, I mean minimizing the amount of information you need to keep in your head to make a simple change. Take this component, for example. It's a grid of links to different parts of the app that users will see in their dashboards, but different users will see different links depending on which type of user they are and also on which plan they have. For example, a regular user on the basic plan will only see these four links. Now imagine we want to make a change, like adding a new link to this particular group of users. Here's what the implementation looks like. It's pretty clean, and I see that I have a list of links there, so I know that's where I need to go and add my new link. I see that we're filtering the links based on the user and the plan, which is great because that's exactly what I need to do, and then we're just rendering the links.
Now this filter links function seems important. I know I need to go in there and change the logic somehow so that it shows my new link to the right sets of users, and when I open this function we might find something that looks like this. Now this is a particularly messy implementation, so don't look too much into it. The important point here is that I now need to completely understand this filtering logic to make my simple small change. So I need to load all of this information in my head in order to make the change. Now imagine if the grid component looks something like this instead. It's very similar and I still have a list of links, but now you see that I can declare which users and plants have access to the link right in the list. So all I need to do is add a new item here and I can move on with my day. Notice that we're still calling the filter links function and for all I care about that function can be very very complex, but now I don't even need to open this function to make that change. I'm spared from having to load all of that logic in my head. This is just one example of how we can reduce cognitive load in our app. Other things we can do include using clear variable names so we don't have to guess what a component or a variable does, writing good comments that don't repeat the code but instead they explain the why and the how, using predefined design patterns because we already have a shared understanding of how they work, and documenting important decisions somewhere, particularly those high level decisions that they just don't belong in a code comment.
The core message of this talk is that simplicity is very hard. Making things easy to change and easy to understand is definitely possible but it's not easy at all. Complexity is an impossible enemy. We can never completely eliminate it but we do have some level of control over its growth and I hope that you can use some of the strategies that we covered today to slow it down before it takes over your code base. If you enjoy talking about complexity, software design and architecture you can find me online as charca in all the socials and also on my website frontend.skl where I write about software design and architecture for frontend developers.
Comments