Java Platform Renaissance: 42 Practical Design Patterns
My work, my first book, was recently published. The book I've been working on for about a year. Although the actual work took about a year, refining the idea and things about the examples started quite a while before this work even started. And I'm not just talking about studying or contributing to the development of the Java platform itself. I mean hours of meetings, discussions, or writing test cases to prove the correctness of hypotheses to find a solution to a critical challenge. And maybe not only that but also time spent helping newcomers, team members, colleagues, or people in charge not only to properly grasp the challenge but also the platform, the tool we are going to use.
The aim of the article is to introduce my newly published book "Practical Design Pattern for Java Developers" (Figure 1., Ref. 7). Together, we'll explore today's application development challenges and dive deeper into some of Java's new language enhancements by exploring the Builder Design pattern in more detail.
The days when applications were developed "ad hoc" seem to have ended only on paper. When it comes to business, "ad hoc" solutions can still be quite common and accepted because the "it just works" argument can be strong enough. Yes, "it works for now" is a winning argument.
Many times such a statement is in direct conflict with the business's understanding, as the unspoken expectation under the hood may be extensibility and maintainability. So, that's the other side of the same coin.
The fact that an application can behave unpredictably after a small extension is not caused by magic, and such a condition could have a negative impact on the use of other practices such as SRE (Site Reliability Engineering, Ref. 4). Many times, the "devil" is hidden in the details of the application's composition and design. The Java platform may seem quite resistant to such "evils''. Such thoughts are partly true because the JVM tries to optimize the code it executes based on its internal statistics, but this is not necessarily successful.
After many years of cross-industry experience, I got the opportunity to get my insights together in the newly published book "Practical Design Pattern for Java Developers." The book is not only a collection of 42 design patterns that are being put into today's context, but it also includes a mostly lightweight introduction to the Java platform followed by many examples. These examples are linked to the use of the patterns in the OpenJDK source code.
Although the beautiful pronic number 42 (Figure 2., Ref.6) may seem magical, the selected 42 patterns should provide a final solution to help application designers create a maintainable and extensible code base, along with a strong reflection on new Java enhancements.
My "secret wish" is that the book will help the community to easily adopt all the improvements that have been added to the JDK, not only to noticeably reduce the language verbosity but also to increase productivity, maintainability, and code security.
Let’s, for instance, explore together one of the most useful creational design patterns, the Builder (Example 1.). We apply it in light of the newly added record class type (Ref.5.).
Let's say that we would like to create an immutable class, "SuperVehicle," with multiple fields. Fields can be very complex, and not all values are known at the same time. The resulting product should be immutable with assessors and comparable to similar types. It means implementing hashCode and equals. The newly added record class provides us with such functionality.
Implementation of the builder pattern using a record class type:
record SuperVehicle(Part engine, Part cabin) implements Vehicle {
static final class Builder {
private Part engine;
private Part cabin;
Builder(){}
Builder addEngine(String type) {…}
Builder addCabin(String type) {…}
Vehicle build(){
return new SuperVehicle(this);
}
}
private SuperVehicle(Builder builder) {
this(builder.engine, builder.cabin);
}
@Override
public void move() {…}
@Override
public void parts() {…}
}
System.out.println output:
SuperVehicle[engine=RecordPart[name=super_engine], cabin=RecordPart[name=super_cabin]]
The presented builder pattern approach is one of many possible approaches that meet the needs of the enterprise. A careful reader may have noticed a private constructor that denies instantiation from "outside" and that the class contains a static final Builder class. The builder provides the fields that are required to create a new SuperVehicle instance. The presented builder pattern uses a newly added record class type. It is straightforward, transparent, and less error-prone than using multiple constructors, sometimes called the telescopic pattern. The SuperVehicle record class automatically includes assessors, hashCode, equals, and toString methods. As the cherry on top, the class is immutable by definition. Isn’t that wonderful?
Conclusion
The newly updated builder pattern can contribute to the sustainability of the application code base as well as the stability of the application at runtime. It conforms to SOLID design principles and represents the power of APIE, the object-oriented programming pillars (Ref. 7)
What is more important, together, we’ve explored a possible implementation of the builder pattern using one of the new Java enhancements.
The book contains many other examples with different implementation proposals. The text will also show the concurrent nature of the Java platform itself, provides the required description of the platform inside, and discusses several concurrent design patterns commonly present in today’s application design.
Together in this book, we will explore not only patterns but also the many anti-patterns that can be considered a natural byproduct of application development. The book describes how to identify and respond to them.
Everything is packed into a compact design and supported by closely discussed examples published in the GitHub repository(Ref. 1).
Any potential reader can find community feedback under my book title to ensure the book's validity to the ongoing Java renaissance (Ref. 8, Ref. 9, Ref. 10, Ref. 11)
Enjoy reading, happy thinking, and coding.