How to Safely Subtype in Java

As you might remember, the Liskov Substitution principle is all about promises and contracts. But exactly what promises? It's about guaranteeing safety in subtyping. It means subtypes have to maintain a guarantee that someone could reasonably infer from the supertype. It must have a transitive relation. In mathematics, we say for all a, b, c ∈ X, if aRb and bRc, then aRc. In object-oriented programming, subclassing (now, in this article on subclassing, I mean subtyping) implies subtyping, but not in the right way. We have to make sure we do not break the superclass promises that we inherit and that we do not depend on something that may change out of our control. If it changes, the other object(s) can be impacted (as they are immutable). In fact, subclassing can even be the source of bugs in the project.

Why Safe Subtyping

Exactly, in fact, subclassing is a special type of subtyping that allows subtype reuse of the supertype implementation (with aims of preventing the re-implementing of everything for small modification in the supertype). We can say subclassing is subtyping but not that subtyping is subclassing. Subclassing brings two things: subtyping (polymorphism) and code reuse. Subtyping has the highest impact power; any changes in the public and protected levels of the superclass will impact its subclasses. Subtyping is not an Is-A relationship, sometimes it's an Is-A relationship. Indeed, subtyping is a procedural technique for code reuse and a tool for dynamic polymorphism.

Filterer Pattern in 10 Steps

Filterer is a pattern that should be applied only in special cases. In the original post, I presented a very simple example intended to show how to apply it. In this post, I present a much more detailed example that's intended to also explain when and why you should apply it.

Introduction

This post consists of 10 short, easy steps on how to correctly implement the filter pattern. In each step, I introduce the requirements of the following two types: