Java Application Architecture
Modularity Patterns with examples using OSGi

Back

Modularity Patterns with examples using OSGi

Back

Modularity Patterns with examples using OSGi

Back

Even though we try not to, we all make mistakes. Except for Randy. I worked with him for a while. He was never wrong.

Anyway, if you do find mistakes on this website, or in the book, please do let me know.

Modularity Patterns with examples using OSGi

Back

Kirk Knoernschild is a software developer who has filled most roles on the software development team. In 2002, Mr. Knoernschild wrote the book "Java Design: Objects, UML, and Process," published by Addison-Wesley and was a contributing author to "No Fluff Just Stuff 2006 Anthology." Kirk is an open source contributor, has written numerous articles, and is a frequent conference speaker. He has trained and mentored thousands of software professionals on topics including Java/J2EE, modeling, software architecture and design, component-based development, service-oriented architecture, and software process. You can visit his website.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Manage Relationships

Statement

Design module relationships.

Description

A relationship between two modules exists when a class within one module imports at least a single class within another module. In other words:
If changing the contents of a module, M2, may impact the contents of another module, M1, we can say that M1 has a Physical Dependency on M2. [JOUP02]

Modularity Patterns with examples using OSGi
data-theme="b"

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Module Reuse

Statement

Emphasize reuse at the module level.

Description

One of the oft-cited benefits of object oriented development is reuse. A large part of its failure is because classes aren't the best reuse mechanism.
Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Cohesive Modules

Statement

Module behavior should serve a singular purpose.

Description

There are two key elements that affect module cohesion. These follow: Based on these statements, it's easy to draw the following conclusion:

Unfortunately, while logical, these general statements do not always apply.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Acyclic Relationships

Statement

Module relationships should be uni-directional.

Description

When you define a relationship between two system modules, their coupling is increased. Some degree of coupling is necessary simply because modules need to work together to accomplish some task. But certain types of coupling should be avoided. There are rules that will help you identify bi-directional relationships between modules.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Levelize Modules

Statement

Module relationships should be levelized.

Description

Levelized modules demand that module relationships be acyclic. Any cycles in module relationships therefore prevents levelization. To levelize modules relationships, there are several steps.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Physical Layers

Statement

Module relationships must not violate logical layer relationships.

Description

It's common knowledge that when designing systems of any degree of complexity, the presentation, business logic, and data access should be separated into distinct layers. There are several important considerations when separating the layers.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Container Independence

Statement

Modules should be independent of the runtime container.

Description

Modules with excessive runtime container dependencies are heavyweight modules that cannot execute outside the confines of the runtime container. Lightweight modules with no container dependencies have significant advantages.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Independent Deployment

Statement

Modules should be as independently deployable as possible.

Description

For a module to be independently deployable, it cannot have any outgoing dependencies on any other module.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Published Interface

Statement

Make a modules published interface well-known.

Description

A modules's PublishedInterface is the set of public methods on the public classes within the module that you expect developers using the module to invoke and work with. A PublishedInterface is subtly different from a modules public interface, which is simply the complete set of public methods on public classes within the module.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

External Configuration

Statement

Modules should be externally configurable.

Description

The ability to configure a module to it's usage context increases our ability to reuse the module across contexts, whereas tightly coupling configuration to the module prohibits reuse. External configuration allows a module to be reconfigured across environments, and even within it's existing environment, without demanding redeploying the module.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Default Implementation

Statement

Provide modules with a default implementation.

Description

To maximize reuse, a module must be flexible enough so that it can function in variety of different operating environments. Yet, for a module to be usable, it must be independently deployable. To address this tension, a module can be given a Default Implementation with well-defined extension points so that the module can be extended when necessary.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Module Facade

Statement

Create a facade serving as a coarse-grained entry point to the modules underlying implementation.

Description

We create fine-grained and lightweight modules to increase module reuse. Unfortunately, fine-grained modules can also be difficult to use because the user must understand the API of several different modules and use them in conjunction with each other to accomplish a particular task. Additionally, lightweight modules must also be configured to an environmental context. Because of this, fine-grained and lightweight modules are generally more difficult to use. A Module Facade is useful to provide a higher level API that coordinates the work of a set of fine-grained modules.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Abstract Modules

Statement

Depend upon the abstract elements of a module.

Description

Modules heavily depended upon have many incoming dependencies. In other words, you may have many modules that all depend on a single module. On one hand, this is a good thing because you've managed to maximize reuse. But reuse has it's challenges. If the modules you're reusing heavily require a change, the ramifications of that change can ripple throughout all dependent modules. Changing a heavily reused module can be quite a maintenance headache. Abstract Modules helps you deal with this dilemma.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Implementation Factory

Statement

Use factories to create a modules implementation classes.

Description

One of the challenges we face with Abstract Modules is how the object relationships are established at runtime. A class dependent on an abstraction should avoid referencing any of the implementing classes, otherwise anytime a new implementation class is defined, the class dependent on the abstraction also needs to be changed.
If a class depending on an abstraction must be changed when creating a new implementation of the abstraction, the design is flawed.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Separate Abstractions

Statement

Place abstractions and the classes that implement them in separate modules.

Description

You create an abstract class or interface to help reduce coupling between classes. This offers the ability to create new implementations of the abstraction without impacting clients dependent on that abstraction. In this sense, abstract coupling allows you to add new classes to your system without modifying existing classes, and it does so by reducing the dependency relationship between classes.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Collocate Exceptions

Statement

Exceptions should be close to the class or interface that throw them.

Description

Sadly, dealing with exceptions in enterprise software systems is often an afterthought. But allocation of exceptions to modules has significant implications on the modularity, and more specifically the dependencies between modules, within our software system. Placing the exception close to a class that catches it will often cause a cyclic dependency between the module containing the class that throws the exception and the module containing the class that catches the exception. Exceptions should always be placed in a module closer to the class that throws the exception than a module closer to the class that catches the exception.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Levelized Build

Statement

Perform the build in accordance with module levelization.

Description

An automated and repeatable build is a critical aspect to most successful development projects. First and foremost, an automated and repeatable build forces you to integrate early and integrate often, so you’re guaranteed to always have a system that works. But there are some rules you should follow to implement a Levelized Build.

Modularity Patterns with examples using OSGi

Back

For the full description, implementation variations, consequences, and detailed sample, see Page 150 in Java Application Architecture.

Test Module

Statement

Each module should have a corresponding test module.

Description

Writing tests is one of the most important activities you should perform as a developer. Create a robust suite of tests has significant advantages, both long and short term. Short term, tests help you verify that the code you write does as you intend. Creating tests also helps you design your system. Since classes should be independently testable, a natural by-product of test driven development is that your classes will exhibit lower degrees of coupling. Testing classes independently is valuable, but it's also valuable to test the integration aspect of multiple classes or modules.

Modularity Patterns with examples using OSGi