Unleashing the Power of Java Interfaces

Java interfaces, for a very long time, were just that — interfaces, an anemic set of function prototypes. Even then, there were non-standard uses of interfaces (for example, marker interfaces), but that's it.

However, since Java 8, there have been substantial changes in the interfaces. Additions of default and static methods enabled many new possibilities. For example, enabled adding of new functionality to existing interfaces without breaking old code. Or hiding all implementations behind factory methods, enforcing the “code against interface” policy. The addition of sealed interfaces enabled the creation of true sum types and expressions in code design intents. Together, these changes made Java interfaces a powerful, concise, and expressive tool. Let’s take a look at some non-traditional applications of Java interfaces.

Function’s Anatomy and Beyond

Writing clean, understandable, easy-to-support, and maintain code is hard and requires many years of experience. At least we're used to thinking this way. What if there is a way to write such a code consciously and without spending years and years developing these skills?

Functions, Functions Everywhere…

Function Function Everywhere


The Saga Is Antipattern

The Saga pattern is often positioned as a better way to handle distributed transactions. I see no point in discussing Saga's advantages and disadvantages because Saga should not be used at all in the microservices-based systems:

If you need distributed transactions across a few microservices, most likely you incorrectly defined and separated domains.

The Context: Introduction

Every software project has its own aura. That aura existed before the project was even started. It gave birth to the project and will be alive when the project will be decommissioned and/or replaced with some other project. This aura is The Full Context.

The Full Context consists of all information directly or indirectly related to the project. It's the single source of truth for every single decision related to the project, from the decision to start it to the name of every variable in the code.

We Should Write Java Code Differently

For the last few years, I’m writing articles that describe a new, more functional way to write Java code. But the question of why we should use this new coding style remains largely unanswered. This article is an attempt to fill this gap.

Just like any other language, Java evolves over time. So does the style in which Java code is written. Code written around Y2K is significantly different from code written after 2004-2006 when Java5 and then Java6 was released. Generics and annotations are so widespread now, that it’s hard to even imagine Java code without them.

Introduction To Pragmatic Functional Java

The Pragmatic Functional Java (PFJ) is an attempt to define a new idiomatic Java coding style. Coding style, which will completely utilize all features of current and upcoming Java versions and involve compiler to help writing concise yet reliable and readable code.

While this style can be used even with Java 8, with Java 11 it looks much cleaner and concise. It gets even more expressive with Java 17 and benefits from every new Java language feature.

Why Builder Is Often an Antipattern and How to Replace it With Fluent Builder

The Builder Pattern is extremely popular in Java applications. Unfortunately, it's often misunderstood and incorrectly applied, which results to runtime errors.

Let's remember the purpose of Builder: set only necessary fields in some object and keep remaining fields set to default values. For example, if we're preparing a configuration object, then it's convenient to change only the necessary parameters and keep other parameters set to default values. 

Don’t Do Microservices If You Can

In the last few years, there has been a wave of hype that crosses IT-dedicated media back and forth, growing bigger and bigger. And this wave is about microservices.

Countless articles, blog posts, videos, and slideshows dedicated to microservices, how to design them, or how to apply them to existing applications.

Data Dependency Analyses in Backend Applications

Data Processing Patterns

Every application somehow deals with data. After all, this is why applications are necessary in the first place. 

In the case of backend applications, there are well-known stable patterns for how code deals with data. Everyone knows about CRUD, for example. 

Consistent Error Propagation and Handling in Java

Learn more about consistent error handling and propagation in Java.

Every application lives in the real world, and the real world is not perfect. So even the ideal, bug-free application is doomed to deal with errors from time to time.

The problem has existed since the birth of the first computer program, and software engineers invented many ways to deal with errors!