There have been multiple architectural paradigms over the year, but all of them have one key goal: managing complexity. How can we package code into components and work with these components as abstract entities to infer about and build chunks of behavior?
These components divide the system into partitions, so that each partition has a specific concern and role. Each component has well defined interfaces and responsibilities and is segregated from the rest of the components. Having this abstraction allows us to not worry about the inner workings of the components.
System decomposition needs to be a well thought-out activity. There are two key metrics for assessing how good your components are, named cohesion ...