
Loosely coupled components
The best way to address a complex subject has always been to divide it into smaller sub problems that are more manageable. As an example, it would be insanely complex to build a house in one single step. It is much easier to build the house up from simple parts that are then combined into the final result.
The same also applies to software development. It is much easier to develop a very complex application if we divide this application into smaller components that interoperate and together make up the overall application. Now, it is much easier to develop these components individually if they are only loosely coupled to each other. What this means is that component A makes no assumptions about the inner workings of, say, components B and C, but is only interested in how it can communicate with those two components across a well-defined interface. If each component has a well-defined and simple public interface through which communication with the other components in the system and the outside world happens, then this enables us to develop each component individually, without implicit dependencies to other components. During the development process, other components in the system can be replaced by stubs or mocks to allow us to test our component.