Rethinking Separation of Concerns with React
Understanding the true nature of separation of concerns is one of those topics that separates newbies from the seasoned developer. There’s more to code than just getting the syntax right. Beautiful code is one that is modular, loosely coupled and extremely easy to maintain. I’ve been thinking about long term feasibility of React and SoC over the past few days since my original deep dive into the framework.
When Angular 1 came out, everyone was excited because of how easy it was to do things. But as projects grew, complications started to arise — especially when there are multiple people working on a single code base. One could argue that it is the nature of programming — and perhaps it is, but it doesn’t have to be. Angular 2 came out and forced a stronger separation of concerns through explicitly requiring different types of files for different functionality. HTML lived in one file. Your component logic lived in another file. Relevant CSS is automatically localized to a single file and your services in another file.
React challenges this way of thinking by encouraging you to put everything into one space.
What is separation of concern?
separation of concerns (SoC) is a design principle for separating a computer program into distinct sections, such that each section addresses a separate concern — Wikipedia
Separation of Concern is supposed to help keep the code organized. A ‘concern’ is a particular set of information that is related to each other within the immediate vicinity. In short, separation of concern is a classification method.
If you think about your local supermarket, each item categorized into item types. The sorting of all oranges, apples, and bananas into their different and grouped arrangement makes it easier for shoppers to chose which fruit they want. However, efficiency and sales are increased when related products are grouped together — like pasta and pasta sauce or rice and butter chicken mix. There is less walking required and the grouping of ingredients makes it easier to determine what else you need.
From what I understand, separation of concern is all about organization and the conventional philosophy goes — group like and like together. Angular does this through file types. They don’t mix JavaScript and HTML together like React.
However, this isn’t the only style available when it comes to organizing code and separating out their domain of concerns.
Just because it’s a popular convention, doesn’t mean its right
React challenges the traditional models of thinking towards separation of concern.
The diagram below illustrates how MVC frameworks often structure their files and content. Separation of concern is determined by the file type and may be grouped together in a file of sorts.
This structure is common in templating styled frameworks. However, the issue with this structure is that when problems or new features arise, it’s often implemented horizontally.
The point of SoC is so that code remains maintainable and is mentally digestible by the developer. There’s no point of splitting code into a million different files if no one can understand it. We’re only human and have a finite short term memory computing space. SoC is supposed to reduce the load by grouping like for like together.
The idea behind grouping like for like is also to reduce code coupling and increase cohesion. This means that a piece of code is independent from each other and can easily be interchanged like lego parts.
However, that is often not the case — especially in templating frameworks like Angular. In large projects, this can actually increase code interdependency if you’re not careful. As we are forced to move horizontally and across multiple files, the structure and method behind this style of SoC make the code harder to maintain and understand. It gets even worse when an unmoderated junior enters the fray and it’s not their fault, not really.
Challenging traditional thinking for Separation of Concern
When Angular 1 came out, it was groundbreaking because it made view binding work like magic. It just worked.
Then projects grew and grew, and everything started to fall apart. The partials started to get used everywhere and the originally separated templates became unwittingly interconnected. If you wanted to change something, you also needed to trace horizontally across the files and figure out what else is affected.
Things get messy and soon, you’re more worried about breaking the code than writing it.
React challenges the traditional method of file silos by flipping it on its side and group their code based on relationship to each other. Language is not a hard line barrier but is seen as one cohesive and logically related block. With React, there is no templating — just components that can be created and destroyed as required.
When code is grouped together based on relationship rather than an arbitrary requirement, processing the block becomes easier.
The original mentality behind separation of concerns was created by the early pioneer in computing scientist Dijkstra in 1974, and in short, the purpose of SoC is the “effective ordering of one’s thoughts” React does this by turning grouping code into digestible blocks of code where the flow of logic can be easily traced.
We’ve since evolved from the long single files and coding styles of the 80s and 90s — but that doesn’t mean that the current and popular methods are 100% correct for our needs either. That’s why frameworks are created and the ones that solve major problems experienced in other frameworks are the ones that thrive.
Someone will still have to play the code janitor
The point of frameworks is that they provide a scaffold for how you write your code. React takes this scaffold away and you’re free to structure the code however you want. SoC is designed for you when it comes to Angular. React lets you design your own and there is no limitation on how you arrange your code.
You’re still going to need a code janitor nevertheless. It doesn’t matter how good a framework is, if not used properly, code will still fall apart. There still needs to be that one person that takes a step back, create the required conventions for the project and enforce it on everyone else. The code janitor plays an important role of keeping the code organized and ensure that modules and components remain cohesive rather than tacked on.
The code janitor usually comes in the form of the tech lead. There is usually a code review to ensure that the code fits the way its supposed to — structurally, stylistically and functionally. No one is perfect and someone is bound to inject or do something weird sooner or later. Projects usually fall apart in the long run without a code janitor to keep everyone in line and clean after their own messes.
The thing you must also acknowledge and remember is that all major and popular frameworks solves a problem of sorts — but the most effective one is the one that solves your problem. Every project and every team has their own personal styles and issues that they will encounter. Separation of concern works best when it serves the needs and future growth of the project, along with the team’s ability to understand and how much documentation they’re capable of processing.