2.5 Modular Design Concepts
Given these constructs, how do we talk about OSGi-based applications? One way is to look at the abstraction hierarchy:
- Application > Bundle > Package > Type > Method
This shows that a bundle is an abstraction that is bigger than a package but smaller than an application. In other words, an application is composed of bundles; bundles are composed of packages; packages are composed of types; and types are composed of methods. So, just as a type is composed of methods that implement its behavior, an application is composed of bundles that implement its behavior. The task of decomposing an application into bundles is similar to that of decomposing an application into types and methods.
Another way to talk about OSGi-based systems is to talk about decomposition. Key to high-quality design at all levels is the decomposition used. We talk about and measure decomposition along three axes: granularity, coupling, and cohesion. Here we relate these terms to the OSGi environment:
- Granularity—Granularity is the measure of how much code and other content is in a bundle. Coarse-grained bundles are easy to manage but are inflexible and bloat the system. Fine-grained bundles give ultimate control but require more attention. Choosing the right granularity for your bundles is a balance of these tensions. Big is not necessarily bad, nor small, good. In some ways granularity is the overarching consequence of coupling and cohesion.
- Coupling—Coupling is an outward view of the number of relationships between a bundle and the rest of the system. A bundle that is highly coupled requires many other bundles and generally makes many assumptions about its surrounding context. On the other hand, loosely coupled bundles operate independently and offer you the flexibility to compose your application to precisely meet your changing requirements without dragging in unnecessary dependencies.
- Cohesion—Cohesion is an inward view of the relevance of the elements of a bundle to one another. In a highly cohesive bundle, all parts of the bundle are directly related to, and focused on, addressing a defined, narrowly focused topic. Low-cohesion bundles are ill-defined dumping grounds of random content. Highly cohesive bundles are easier to test and reuse, and they enable you to deliver just the function you need and nothing more. A common pitfall is to consider a bundle to be either an entire subsystem or an entire layer in the application's architecture, for example, the domain model or the user interface. A highly cohesive bundle often provides a solution to part, but not all, of a problem.
These ideas are not unique to OSGi—they are tenets of good design practices and fundamental to object-oriented and agile approaches. In the case of OSGi, however, the system is designed to expose and enforce key aspects of coupling, cohesion, and granularity, making the benefits directly tangible. OSGi encourages you to decompose your application into right-grained bundles that are loosely coupled and highly cohesive.