#📚reference
Modularity is probably one of the most important concepts in software engineering. In general, modularity can be expressed as:
> Things that work together should be put together.
Another intuition behind modularity is that it would be logical to expect that our software products are organized according to the problem breakdown we performed during their decomposition. This particular approach is also called domain-driven design.
In modular architecture, we are concerned with finding an optimal way of splitting software products into pieces we can develop and sometimes deploy independently. The goal is to split our application in such a way that small and medium changes can be performed by augmenting as few components of the system as possible. This involves cutting the system into several layers, separating components according to their responsibility, extracting certain parts into reusable libraries or services, and so on. Usually, we call such a separate piece a module.
Since there are many ways to split something, people develop a set of guiding principles. One of the most important, if not the most important, is the single responsibility principle, according to which we should break down the system into components, each responsible for one single task. While the single responsibility principle could be too restrictive, the responsibility itself is usually the best way to decide how the system should be separated into smaller pieces.
Modular architecture is crucial for building secure and reliable software products. From the [[security]] perspective, we want components with privileged access to be as isolated as possible. While the quest for [[reliability]] demands that we don't want failure in one part of the system to trigger a chain reaction leading to a fatal system crash.
But there is more to that. A good modular design takes into account not just the current or upcoming state of a codebase but the entire [[development process]] and [[product management]] policies.
This means that we want to take into account the structure of the engineering team and the way product decisions are made. For example, we might extract a critical piece of functionality into a separate module or service and restrict the change to a special group of skilled engineers with a deep understanding of the company's business model.
Or, following a similar logic, if a company relies on contractors, we might design a system so that these contractors will work mostly on the modules they are responsible for.
Basically, this extends the responsibility principle in a strict sense to processes and tech team formation and meets the general notion of responsibility.
---
<font style="color: #F86759">Contributors:</font> *[[Mykhailo]]*
<font style="color: #F86759">Last edited:</font> *2024-03-27*