View More

This post is about the value object pattern and the factory pattern which are tactical patterns in domain driven design (DDD). Value objects define the second kind of domain objects besides entities. Their main characteristic is immutability: Attributes of a value object never change.

Factories are responsible for creating new objects and validate them. They help us identify and separate this functionality from the other parts of a domain object.

Value Objects

Value objects do have attributes and methods as entities. Attributes of value objects are immutable though which implies that methods of value objects can only be queries, never commands that change the internal state of an object. We can pass value objects to clients through getters for example without worrying that they change them.

Many objects can be modeled as value objects instead of entities because they are defined through their attributes. These objects measure, quantify or describe things in the domain model. Because they are so easy to handle we should model as many value objects as possible.

No identity, no lifecycle

Value objects don’t have an identity that is used to compare them. We compare them by their attributes. When all attributes of a value object match another one they are considered equal. Therefore we can construct a value object from its attributes when needed and destroy it afterward.

Without the burden of maintaining an identity (create a unique id, associate it with other entities) value objects are a lot easier to handle than entities.

Example

An example of a value object is the material of a tabletop. The tabletop’s main material can be wood, stone or steel for example. Instead of adding attributes for kind (wood, steel), name (oak, chromium steel) and thickness directly to the table object let us create a value object called material.

Now the material is explicitly defined and named. We can interact with the table without thinking about the details of the material.

Maybe you decide the replace the tabletop with another after some years. However, because value objects are immutable, the material object cannot be changed. We replace it with the new one. Just like in the physical world, stone can’t be transformed into wood magically.

In code, the replacement boils down to setting new attributes and save them to persistence. If we modeled the material as an entity with identity, we first would need to delete the old material, generate a new id and associate it with the table object.

Now on to the second pattern of this post, the factory.

Factory

The factory pattern in DDD can be seen as a super pattern for the Gang of Four (GoF) creational patterns. Factories are concerned with creating new entities and value objects. They also validate the invariants for the newly created objects. We can place a factory on the entity or value object itself or an independent object.

Factories that are placed on the same object they create are either factory methods or prototype methods. The factory method creates a completely new object from the method parameters. The prototype method uses an existing instance to derive a new object.

When the creation logic is complex or has dependencies that are not needed by the created object it is best to create a separate factory. This factory could then provide multiple ways to create new instances.

Wrap Up / Final Thoughts

Value objects simplify our lives by releasing us from thinking about mutated state just like in the functional programming style. By combining them with entities, we can get a simple but powerful model within our code.

Factories draw a clear line between creation logic and other concerns in the code. When we name them explicitly and consistently, readability of our code should be improved.

[Eva04] Eric Evans: Domain-Driven Design – Tackling Complexity in the Heart of Software (homepage)

View More

Continuing the series about modularization patterns with Java 9 today I would like to introduce the patterns Default Implementation and Module Facade [Kno12]. As its name suggests, the Default Implementation pattern is about providing implementations for abstract modules but also default configuration. Facades are a well-known pattern from [GoF] which can be applied to modules too as we will see.

The Problem

When we try to make modules flexible, we create abstract modules that separate implementations from abstractions and configurations. These now flexible modules are harder to use because users need multiple modules (abstraction and implementation) or external configuration.

Even if there is an implementation provided for a given abstraction, users should not depend on it. We need some mechanism that wires the implementation to the user.

The Solution

The solution to the above problem is to provide default implementations of abstractions and default configuration settings. We deploy default configurations normally within the same module, default implementations can be deployed within the same module or in a separate module.

We should also provide means to obtain default implementations without requiring users to depend on them directly. With the java platform module system (JPMS) we can use services to obtain default implementations as can be seen in the following sample.

Default Implementation Sample

The sales module of our ongoing webshop sample provides an API to apply a discount to the sales. Different implementations are provided by other modules that calculate a discount based on various criteria. In many use cases, however, there won’t be a discount applied. The customer needs to pay the full amount.

As you can see, the sales module provides a default implementation of the discount calculator. It covers the case where no discount needs to be calculated. From the three services that use the sales module, two provide an implementation of the discount calculator and one doesn’t. Another case that I don’t show here and which doesn’t provide an implementation could be the test module.

Without further actions, users need to create this default implementation themselves and therefore have a dependency on it. To prevent this undesired dependency, we have at least two options: Add a factory [GoF] or provide the discount calculator as a service. Because the factory pattern is already well-known, I  choose the service option for this sample.

The following module descriptor of the sales module declares a uses dependency on the discount calculator. At the same time, it provides the default implementation as a service.

The default implementation will be used as long as no other module provides one with a higher priority. When a new requirement arises to provide a different implementation of the discount calculator, it can be implemented in a different module and plugged in the application without changing the sales module.

Default Configuration

In this post, we saw the external configuration pattern which enhances the flexibility of the module. The sample was about configuring the URL of a REST call for different environments. Every developer that wants to use that module needs to provide a configuration for it which makes it harder to use.

To improve the situation, we could add a default configuration inside the module that points at some localhost URL. Then the developers would not need to provide a new configuration each time they want to reuse the module.

Module Façade Pattern

The Module Façade pattern [Kno12] seeks to improve the usability of multiple smaller modules. When we focus on flexibility and reuse, we tend to create many small modules. Those small modules become harder to use because of their fine granularity.

A module façade provides a common API for multiple smaller modules. It may also contain configuration for them and even add functionality itself.

Sample Facade

Suppose we want to manage different product categories as independent modules. For example, we could have a home electronics module and a pc module. They both share common functionality of the product base module but add their own search and filter options.

To ease the use of those product category modules, we create a product module as a façade which includes the home electronics, pc and base modules. Users now only need to add a dependency on the façade without worrying about the different categories. When more categories are added, users automatically get access to them too without needing to modify their dependencies.

Wrap Up / Final Thoughts

When we want to use a module, it should work out of the box. If we need to find an implementation of an abstract module or need to add multiple dependencies to make it work, we are distracted from our actual task. If we design modules according to the two usability patterns default implementation and module façade, live for the users of our modules (which could be ourselves too) is greatly simplified.

[Kno12] K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (homepage)

[GoF] Design Patterns: Elements of Reusable Object-Oriented Software (wiki)

View More

In this post, we look at two usability patterns: Published Interface and External Configuration. Usability patterns help to integrate modules with each other and generally simplify development with modules.

When working with a module, the developer needs to know how he is supposed to use it. The published interface pattern acknowledges this and focuses on a clearly defined API for modules. Another problem that we may face when using modules and especially re-using them is that we may need to change some configuration values. To allow this without recompilation of the module configuration can be located outside of the module as the external configuration pattern proposes.

Published Interface

The published interface pattern [Kno12] states that one should make the API of a module well known. What is part of the public API of the module and equally (or even more) important what is not? It is important to make this obvious for anyone using your modules. If we don’t, users (like ourselves next month) will certainly access elements of the module that we did not intend to. Afterward, we cannot change such elements easily without breaking code that uses the module.

Before the java module system, it was impossible to enforce usage of the public API. With the module system, we can publish it and prevent usage of elements by only exporting the required packages and providing services.

The Sample

Continuing the webshop sample let’s have a look at the customer component before refactoring it to modules. It contains implementations for consumers and business customers. They both implement a shared interface and users should use the factory to create them. The files are organized as follows:

Without the module system, it was possible for users to create the implementation types directly without using the factory. They could access the implementation types directly. Therefore, any change to these classes could have a big impact on users of the component.

Now we refactor to a module by adding the following module descriptor:

It is now impossible for users of our module to use the implementation classes directly. We have not only published the interface by explicitly stating exported packages but also prevent access to the others.

External Configuration

Another usability pattern introduced by [Kno12] is external configuration. It states that we should make modules externally configurable. When we create modules that are configurable the chances that they can be reused are increased.

Sample

In many projects, there are multiple stages or environments involved when deploying an application. Maybe there should be at least two, one for testing and the production. To deploy a module to multiple environments it needs to be configurable. For example, the sales module from the webshop application posts an event to a REST endpoint when a sale was completed. It, therefore, needs to know the URI of the endpoint which is different for each environment. We configure the URI externally through a properties file which we deploy next to the module JAR file.

With this setup, we can provide a different settings file for each environment. It probably would be easier to store the properties files inside the module, but then we would need to rebuild it for each environment.

Wrap Up / Final Thoughts

In this post, we saw two usability patterns that simplify usage and maintainability of modules. With the published interface we can ensure that our modules are used as intended. The external configuration allows for reusable modules that can be configured for different environments or even use cases.

[Kno12] K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (homepage)

View More

The next pattern that I would like to discuss is called “Independent Deployment” [Kno12]. It states that modules should be independently deployable units. For a module to be independently deployable, it cannot have any outgoing dependencies on other modules. In most cases, this is unrealistic, but the dependencies can be minimized.

Why should modules be independently deployable? If we want to reuse a module, every outgoing dependency is needed too. Therefore if we minimize outgoing dependencies, the module is going to be simpler to reuse.

Some dependencies are “lighter” than others and are preferable to “heavier” ones. For example, abstract classes and interfaces are light because they have a lower rate of change than their concrete implementations. A dependency on implementation can be avoided by defining an abstraction and use a wiring technic to get access to the implementation. With the java platform module system (JPMS) we can use services to implement the wiring.

Sample code for this post can be found on GitHub.

The Sample

In the first part of this series, I introduced the web shop as a sample of an application that we would like to modularize. Now we have the following modules in place.

The inventory module depends on baskets to calculate availability. Now imagine if we would like to reuse the inventory module in an application for inventory management where there are no sales with baskets going on. With this dependency in place, we would need to bring along the baskets module too, but there would never be any baskets.

The Implementation

The solution is to define an abstraction for availability adjustments. We create a new interface called AvailabilityAdjuster in the inventory module which is implemented by the basket module. Then we need to wire the implementation from the basket module to the inventory using a JPMS service. The inventory module now only depends on the abstract service interface which could be deployed within the inventory module itself or in a separate module.

This design allows us to deploy the inventory module independently. It is a bit more complex than the previous that allowed direct usage of the baskets module through. That’s a typical tension that we encounter in module design: To get the benefits of reusability, the use of some modules maybe gets harder. Therefore, I would aim for the simpler solution first. When the need arises to reuse some module, there is always the possibility to refactor.

Another Option

The sample above uses a callback to break (or invert actually) the dependency from the inventory to the baskets module. There is another possibility that may be better in some situations. We could implement escalation to break the dependency. As you may remember from the first part of this series the availability is used by the sales module that displays it to the user. If we move the responsibility to adjust availability according to the contents of the baskets to the sales module the dependency from inventory to baskets can be removed.

With this design, we move functionality to another module. The internal inventory system could implement the same concept of availability through, may be based on what is going to be delivered through the day. Then it may be undesirable to implement two solutions.

Wrap Up / Final Thoughts

Modules should simplify reuse of code. Therefore it should be possible to take individual modules and use them independently. That’s the goal of the independent deployment pattern. It advises how to design or adjust modules to make them reusable.

The JPMS enables us to remove dependencies by converting them into services which can be made optional to use or provided by a simple implementation. In our example, if the inventory system defines no availability adjusters, we can ignore this functionality and still reuse the module.

[Kno12] K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (homepage)

View More

While developing software in Java and other languages, we often create abstractions and separate them from the implementation. This practice has many benefits that we would like to take advantage of while designing modules. The Abstract Module and Separate Abstraction patterns from [Kno12] and API Modules from [Sand&Bak17] deal with abstractions in the context of modules.

Sample code for this post can be found on GitHub.

Abstract Module

The Abstract Module pattern states that users of modules should depend on abstractions, not implementations. When we depend on interfaces or abstract classes the implementation can change without affecting us. It may even be replaced completely by the maintainer of the module. Systems composed of modules that depend on abstractions of each other are flexible and easier to extend.

Sample

You may have come across the sample of payment methods in one form or another already. Let’s see how it looks like with Java 9 modules. If we have a webshop when we check out and complete a sale, there are multiple ways to pay. A first version of the checkout module depends directly on a credit card module and PayPal module as shown below.

As you probably imagine if we add new payment methods the checkout module needs to depend on them too. These dependencies introduce high coupling which we can avoid.

The Refactoring

To prevent coupling the checkout module to every payment method implementation we introduce a payment method abstraction. Now the modules containing payment methods depend on the checkout module.

To make the payment methods usable from within the checkout module, we design the payment method abstraction as JPMS service with the interface PaymentMethod. The payment method modules provide this service with their implementation. Finally the opus.checkout module declares that it will use the payment method services as can be seen in the simplified module descriptors below.

If we need to add more payment options, they can now easily be used by the checkout system without affecting its dependencies. It is also possible for the different implementers of payment methods to change without affecting (rebuild, deploy) the checkout module.

API Modules

The API Modules pattern [Sand&Bak17] states that we should design the API of a module carefully and create dedicated API modules. The API of a module consists of all parts that are exported from it. We should make it as small as possible to gain resilient modules.

Another Refactoring

To apply the API Modules pattern we extend the previous sample with a separate API module called opus.paymentmethod. It contains only the interfaces for using the different payment methods and exports them.

By using the JPMS service infrastructure, we don’t even need to export anything from the implementers. They have zero API and therefore no incoming dependency which allows us to change them without affecting any other module.

The API Modules pattern also states that most parts of the API should be abstractions. This statement aligns well with the goal of the Abstract Module pattern (depend on abstractions) discussed earlier. The API Modules pattern, therefore, can be seen as the inversion of the Abstract Module pattern. If modules only export abstractions other modules can depend only on them and not the implementations.

Separate Abstractions

The third pattern I would like to introduce is Separate Abstractions [Kno12]. It states that we should place abstractions and implementations in separate modules. If they live in the same module, they cannot change independently. Also, an implementation may require additional modules to provide its functionality which are not relevant for the abstraction.

Sample

Suppose our first design introduced an abstraction but located implementations in the same module. This module needs to depend on everything the implementations need like the opus.visaconnector. By refactoring the credit card implementation into its own module, we could remove this dependency from the module with the abstraction (opus.checkout). If there are many different implementations with multiple dependencies, extracting those implementations, helps to keep the modules clean an cohesive.

Where should abstractions live then? If there is only one user of the abstraction, we could place it in the same module. Otherwise, we create a separate module on which multiple users can depend.

The implementations live in their own module. This module needs to depend on the abstraction which could be problematic when it is located in the same module as the user of it. To resolve this problem, we could create a separate abstract module even if there is only one user of it. We applied this already in the second refactoring of the payment method sample.

Wrap Up / Final Thoughts

Abstractions are an integral part of software development. With modules, multiple questions arise regarding when to create them and where they should live. The patterns described in this post should help you answer those questions.

There is always a tension between (re-)usability and flexibility when designing modules. Modules that export abstractions and provide implementations too are easier to use. API only modules that separate abstractions from implementation are more flexible and have fewer dependencies but can be harder to use.

[Kno12] K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (homepage)
[Sand&Bak17] Sander Mak & Paul Bakker: Java 9 Modularity – Patterns and practices for developing maintainable applications (homepage)

View More

Modularization is the process of organizing code into cohesive units. This process is sometimes tedious and hard to do consistently. Patterns can help to make modularization simpler by providing solutions for some common problems. [Kno12] and [Sand&Bak17] are two books which describe patterns that are concerned with modularity. In this blog post series, I am going to show you how they can be applied using the Java Platform Module System (JPMS).

Sample code for this post can be found on GitHub.

The Pattern: Acyclic Dependencies

Dependencies between modules should never form a cycle. Different kinds of cycles include direct dependencies as well as indirect dependencies over three or more modules. In the diagram below there are two cycles, one between module 1 and 2 and the other indirectly over module 3.


When refactoring existing code to modules, it is often the case that you discover cyclic dependencies between packages that you would like to separate in different modules. However, when you refactor towards acyclic dependencies usability and reuse of the code is improved as you will see in the example below.

Implementation

The simplest way to avoid cycles is to remove dependencies altogether. So before applying any of the methods to break cycles think through the involved dependencies. Are they absolutely required or is there a way to remove them?

If they are required, there are multiple ways to break a cycle in your module dependency graph. These are escalation, demotion, and call-back. The following sections show an example of each of these methods.

The sample

Imagine a web shop application that we want to modularize. It has three components: Product, Inventory, and Sale. When a product is displayed to the user during a session, the sales page checks the inventory for its availability. According to a business requirement, when there are multiple sales going on in parallel, we need to ensure that the availability is always guaranteed. Therefore, the inventory needs to take the baskets of these sales into account when calculating the availability. Baskets are located in the sale component. These dependencies form a cycle between the sale and inventory components as shown below.

The Refactoring

When we refactor the components to modules without change we end up with the following module descriptors:

This code fails to compile because of the cycle. We need to break it by using one of the following methods.

Escalation

The first method is to use escalation. We design an additional module called sale process. This module has a dependency on both the inventory and sale module. When the system shows a product to the user, the sale process is responsible for calculating the availability. It asks the inventory for the stock count and checks the baskets from the sale module. With this change, we can remove the dependencies between sale and inventory altogether.

Demotion

Another way to break the cycle is to create a new module called basket. Both the sale and the inventory module depend on the basket module. We ask the inventory for the availability like before. The inventory, in turn, checks the baskets for ongoing sales.

This is called demotion. We demote functionality to a module on a lower level.

Callback

The third method to break cycles is to use a callback. To implement it we need a new JPMS service called OngoingSalesCalculator with a method ongoingSalesCountFor(Product product). This interface is located inside the inventory module (or a separate module) and implemented within the sale module. The inventory uses the callback to calculate the availability now instead of checking the baskets directly.

With this callback in place, we can remove the dependency from the inventory module on the sales module. By using a JPMS service, we don’t need a main class or a framework to do the wiring. We obtain the callback service directly from the service loader inside the inventory module.

When looking at the above descriptors, it may seem that there is still a cycle between those modules. There is actually one but only at runtime. The inventory module does not depend on the sales module during development and compile time but uses the calculator service only at runtime.

Wrap Up / Final Thoughts

When an existing code base is refactored into modules, the resulting dependency graph may contain cycles. These not only prevent code reuse but make it harder to think about the code and change it. There are multiple ways to break cycles, three of which we have seen in this post. When we break the cycles, individual modules can be reused and should be simpler to maintain.

The next part of this series about modularity patterns will take a look at abstractions in the context of modules. We will discover three patterns which help us design resilient modules: Abstract Module, Separate Abstraction and API Modules.

[Kno12] K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (homepage)
[Sand&Bak17] Sander Mak & Paul Bakker: Java 9 Modularity – Patterns and practices for developing maintainable applications (homepage)

View More

With version 9 of Java, a new module system is introduced into the language. This module system is used internally for the JDK libraries but can be used by the application code as well. In contrast to other module systems like OSGi, the Java Platform Module System (JPMS) is an integral part of the language. Because of this, I hope there will be many modularized java applications in the future.

Why should you modularize your code? This question would be a topic for a blog post in itself, but the main two reasons that stuck with me are: Organize your code in reusable units and manage dependencies. Most of the time we reuse a set of classes together instead of a single one. With modules, we have a convenient way to achieve this. Dependencies in Java are buried inside import definitions. With modules, they are explicitly stated and can be reasoned about without the help of code analysis tools.

Sample code for this post can be found on GitHub.

Module Descriptor

Let’s start with the definition of a module and its dependencies. A module is defined through the module descriptor file called module-info.java. This file must be located at the root of the source folder of the module.

The following snippet shows an example of such a module descriptor.

The descriptor defines a module named opus.address. The name must be unique and follow the same conventions as java package names. The first line inside the curly brackets states that the module exports the package com.opus.adress for use by other modules. Everything that is not explicitly exported by a module cannot be used by other modules of the application.

Dependencies

A module defines its dependencies through the requires keyword followed by the name of the module. When a module requires another one it “reads” this module. Reading a module allows the dependent module to use all public elements of packages that are exported by the read module. Java visibility rules still apply to the exported classes and interfaces.

Every module requires java.base implicitly. When a module uses other modules from the java library, it needs to read them explicitly as java.xml in the above example.

Readability is not transitive by default. Modules requiring opus.address do not automatically read opus.utils. If this is desired you need to add the transitive keyword as follows:

Every module that is requiring opus.address automatically reads opus.utils now. This is called implied readability and is transitive by itself. If opus.utils would have a transitive dependency on a third module, this would too be automatically read by modules requiring opus.address.

Services

Services are an integral part of the modules system. They provide means to decouple API and implementation and are in this sense a kind of dependency injection (DI) or inversion of control (IoC) mechanism. They can even be used in conjunction with common DI frameworks like spring or guice which is greatly explained here.

Providing a service

The following module descriptor shows the necessary parts to provide a service.

AddressRepository is the interface (API) of the service and AddressRepositoryImpl (guess what) the implementation of it. Note that the module does not export the package that contains the implementation. Therefore, the consumers of the service do know nothing about it.

Another module could too provide an AddressRepository with a CSV data source like this:

Consuming a service

Consuming a service is done through a lookup in the service registry. Some of you might know the service registry from previous versions of the JDK where it was used to provide services via metadata. In Java 9 the service registry is repurposed for use with the module system.

When a module provides a service, the module system registers it automatically within the service registry. Our code queries the registry for implementations of the service interface.

When you iterate over the returned iterator, the services are lazily instantiated for you by the service loader.

To instruct the module system to make a service available within our module, we need to declare a uses dependency on it in the module descriptor.

The uses dependencies are only resolved at runtime and don’t lead to an error when there are no repository implementations available. Our code needs to handle the situation when no implementation is available.

Wrap Up / Final Thoughts

I hope this post gave you a basic understanding of how to define modules in Java 9 and how they can help you write modularized code. If you are interested in topics like JPMS, modularity in general or domain driven design (DDD) make sure you subscribe to the opus blog newsletter. I will post a new article about every second Friday. Next up: a series about modularity patterns with samples using the JPMS.