Skip to content

nipafx/demo-jigsaw-advent-calendar

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

↗️ This README only covers one section of the demo. The master branch contains more information.

3️⃣ Services

Jigsaw enables loose coupling by implementing the service locator pattern, where the module system itself acts as the locator.

Rationale

Somebody who recently read a blog post about how cool loose coupling is looked at our code from the previous section and complained about the tight relationship between main and factories. To be more precise she critized that main even knows factories. And just because it has to instantiate some implementations of a perfectly fine abstraction (the SurpriseFactory)!

Having a man in the middle providing us with these implementing instances would remove the direct dependency. Even better, if said middleman would be able to find all implementations on the module path, the calendar's surprises could easily be configured by adding or removing modules before launching.

This is indeed possible with Jigsaw. We can have a module specify that it provides implementations of an interface. Another module can express that it uses said interface and find all implementations with the [ServiceLocator] (for details see main below).

We use this opportunity to split factories into chocolate and quote and end up with these modules and dependencies:

  • surprise - Surprise and SurpriseFactory
  • calendar - the calendar, which uses the surprise API
  • chocolate - the ChocolateFactory as a service
  • quote - the QuoteFactory as a service
  • main - the application; no longer requires individual factories

Implementation

The first step is to reorganize the source code. The only change from before is that src/org.codefx.demo.advent.factories is replaced by src/org.codefx.demo.advent.factory.chocolate and src/org.codefx.demo.advent.factory.quote.

Lets look at the individual modules.

surprise

Nothing changed from before.

calendar

Dito.

chocolate

As before with factories this module must require the surprise module.

More interesting are its exports. It provides an implementation of SurpriseFactory, namely ChocolateFactory, which is specified as follows:

provides org.codefx.demo.advent.surprise.SurpriseFactory
	with org.codefx.demo.advent.factory.chocolate.ChocolateFactory;

Since this class is the entirety of its public API it does not need to export anything else. Hence no other export clause is necessary.

We end up with:

module org.codefx.demo.advent.factory.chocolate {
	// list the required modules
	requires transitive org.codefx.demo.advent.surprise;
	// specify which class provides which service
	provides org.codefx.demo.advent.surprise.SurpriseFactory
		with org.codefx.demo.advent.factory.chocolate.ChocolateFactory;
}

Compilation and packaging is straight forward:

javac -p mods -d classes/org.codefx.demo.advent.factory.chocolate ${source files}
jar -c --file mods/org.codefx.demo.advent.factory.chocolate.jar  ${compiled class files}

quote

Analog to chocolate.

main

The most interesting part about main is how it uses the ServiceLocator to find implementation of SurpriseFactory. From its main method:

List<SurpriseFactory> surpriseFactories = new ArrayList<>();
ServiceLoader.load(SurpriseFactory.class).forEach(surpriseFactories::add);

Our application now only requires calendar but must specifiy that it uses SurpriseFactory. It has no API to export.

module org.codefx.demo.advent {
	// list the required modules
	requires org.codefx.demo.advent.calendar;
	// list the used services
	uses org.codefx.demo.advent.surprise.SurpriseFactory;
	// exports no functionality
}

Compilation and execution are like before.

About

An Advent Calendar Demonstrating Jigsaw EA

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published