open-closed-principlesealed-classjava-17

Sealed classes in Java 17, and the open-closed principle


For the first time in a LTS version of Java (Java 17) we have the sealed keyword that, in a nutshell, give us the possibility to restrict the hierarchy:

public abstract sealed class Person
    permits Employee, Manager {
 
    //...
}

If I want to create a new subclass that extend the Person base class, I have to modify the base class too. Is it this against the open close principle?


Solution

  • The open-closed principle is not a law of physics, but merely a guideline that may be useful in some cases. Another useful principle, from Effective Java, is "Design for extension, or else prohibit it." (Also: "Prefer composition to inheritance".) Personally I find the guidance from Effective Java far more useful than the open-closed principle; designing classes for extension is rife with tradeoffs, often questionable ones.

    Sealed classes can be thought of as a generalization of final classes, just applied at a different level of granularity. Previously, prohibiting extension was only available to concrete classes (final), but now it is available to entire hiearchies.

    But, the premise of the question -- "If I want to add..." -- is in itself questionable. Sealed classes are a mechanism that allows API owners to maintain the integrity of their APIs, by controlling all of the implementations of an abstraction (or by limiting extension to specific extension points.) The API owner has already designed and implemented the hierarchy with the assumption that there is a fixed set of implementations; "adding" to it then really becomes "throwing out their design and replacing it with something different." If an API hasn't been designed for extension, second-guessing the designer's intent is risky business.