Chapter 8. Keep Architecture Components Balanced

Building encapsulation boundaries is a crucial skill in software architecture.

George H. Fairbanks in Just Enough Architecture

Guideline:

  • Balance the number and relative size of top-level components in your code.

  • Do this by organizing source code in a way that the number of components is close to 9 (i.e., between 6 and 12) and that the components are of approximately equal size.

  • This improves maintainability because balanced components ease locating code and allow for isolated maintenance.

A well-balanced software architecture is one with not too many and not too few components, with sizes that are approximately equal. The architecture then has a good component balance.

An example of component imbalance would be having a few very large components that contain a disproportionate amount of system logic and many small ones that dwindle in comparison.

Figure 8-1 gives an impression of component balance and what the ideal situation would be. The least desirable situation is on the top left because changes cannot be made in an isolated component. The ideal situation is shown last, the one with nine components in which it is most likely that maintenance can be isolated to one or two components that have a limited scope. The second situation (top right) suffers from a skewed distribution of volume over components. When one component is extraordinarily large, the architecture becomes monolithic; it becomes hard to navigate the codebase and do isolated maintenance. In the third situation (bottom left), where the architecture is scattered among many components, it becomes hard to keep a mental map of the codebase and to grasp how components interact.

blms 0801
Figure 8-1. System division in components, with worst component balance top-left and best component balance bottom-right

Motivation

Now we know what component balance is, but not why it is important. The reason is simple: software maintenance is easier when the software architecture is balanced. This section discusses in what ways you can benefit from a good system component balance: it makes it easier to find and analyze code, it better isolates effects of maintenance, and it separates maintenance responsibilities.

A Good Component Balance Eases Finding and Analyzing Code

A clear code organization in components makes it easier to find the piece of code that you want to change. Of course, proper code hygiene helps in this process as well, such as using a consistent naming convention (see Chapter 11). When the number of components is manageable (around nine) and their volume is consistent, they allow for a drill-down each time that you need to analyze code to modify it.

In contrast, an unbalanced organization of components is more likely to have unclear functional boundaries. For example, a component that is very large compared to others is more likely to contain functionalities that are unrelated, and therefore that component is harder to analyze.

A Good Component Balance Better Isolates Maintenance Effects

When a system’s component balance clearly describes functional boundaries, it has a proper separation of concerns, which makes for isolated behavior in the system. Isolated behavior within system components is relevant because it guards against unexpected effects, such as regression.

More broadly, isolation of code within components has the general advantage of modularity: components with clear functional and technical boundaries are easier to substitute, remove, and test than components with mixed functionalities and technical intertwinement.

Note that a good component balance in itself clearly does not guarantee isolation of changes. After all, grouping code in different components does not necessarily make those components independent from each other. So, the degree of dependence between components is relevant as well, as we will discuss in Chapter 7.

Important

This reasoning about isolation applies to code on a smaller level as well. For example, a system that consists of small, simple classes signals a proper separation of concerns, but does not guarantee it. For that you will need to investigate the actual dependencies (see, e.g., Chapter 6).

A Good Component Balance Separates Maintenance Responsibilities

Having clear functional boundaries between components makes it easier to distribute responsibilities for maintenance among separate teams. The number of components of a system and their relative size should indicate the system’s decomposition into functional groups.

When a system has too many or too few components, it is considered more difficult to understand and harder to maintain. If the number of components is too low, it does not help you much to navigate through the functionalities of the system. On the other hand, too many components make it hard to get a clear overview of the entire system.

How to Apply the Guideline

The two principles of component balance are:

  • The number of top-level system components should ideally be 9, and generally between 6 and 12.

  • The components’ volume in terms of source code should be roughly equal.

Important

Note that component balance is an indicator for a clear component separation, not a goal in itself. It should follow from the system design and development process. The division of the system into components should be natural, not forced to nine components for the sake of having nine components.

Decide on the Right Conceptual Level for Grouping Functionality into Components

To achieve a good system division that is easy to navigate for developers, you need to choose the right conceptual level for grouping functionality. Usually, software systems are organized along high-level functional domains that describe what kind of functions the system performs for the user. Alternatively, a division is made along the separations of technical specialities.

For example, a system that bases component division on function domains might have components like Data Retrieval, Invoice Administration, Reporting, Administrator, and so on. Each component contains source code that offers end-to-end functionality, ranging from the database to the frontend. A functional division has the advantage of being available during design, before development starts. For developers, it has the advantage that they can analyze source code while thinking in high-level functionalities. A disadvantage can be that developers may need to be proficient and comfortable in multiple technical domains to make changes to a single component.

An example of a system that uses technical division might have components like Frontend, Backend, Interfaces, Logging, and so on. This approach has advantages for teams that have a division of responsibilities based on technology specialization. The component division then reflects the division of labor among various specialists.

Choosing the right concepts for grouping functionality within a system is part of the software architect role. This role may be assigned to a single person, or it may be distributed over various people within the development team. When changes are needed to the component division, those in the architect role must be consulted.

Clarify the System’s Domains and Apply Those Consistently

Once a choice for the type of system division into components has been made, you need to apply it consistently. An inconsistent architecture is a bad architecture. Therefore, the division into components should be formalized and controlled. While making the design choices may be an architect’s role, the discipline to create and respect the component boundaries in the code organization applies to all developers. A way to achieve this is to agree as a team in which components certain changes need to be implemented. It is a collective responsibility to ensure that this is done in a consistent manner.

Common Objections to Balancing Components

This section discusses objections regarding component balance. Common objections are that component imbalance is not really a problem, or that it is a problem that cannot be fixed.

Objection: Component Imbalance Works Just Fine

“Our system may seem to have bad component balance, but we’re not having any problems with it.”

Component balance, as we define it, is not binary. There are different degrees of balance, and its definition allows for some deviation from the “ideal” of nine components of equal size. Whether a component imbalance is an actual maintenance burden depends on the degree of deviation, the experience of the maintenance team, and the cause of the imbalance.

The most important maintenance burden occurs when the imbalance is caused by lack of discipline during maintenance—when developers do not put code in the component where it belongs. Since inconsistency is the enemy of predictability, that may lead to unexpected effects. Code that is placed in the wrong components may lead to unintended dependencies between components, which hurts testability and flexibility.

Objection: Entanglement Is Impairing Component Balance

“We cannot get component balance right because of entanglement among components.”

This situation points to another problem: technical dependence between components. Entanglement between components signals an improper separation of concerns. This issue and guideline are further described in Chapter 7. In this case, it is more important and urgent to fix component dependencies—for example, by hiding implementation details behind interfaces and fixing circular dependencies. After that, you can revise your component structure to improve its balance.

See Also

Component coupling is closely related to the idea of component balance discussed in this chapter. Component coupling is discussed in Chapter 7.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset