I want to know if the below code is violating open closed principle.
Animal
is a parent class of Dog
, however Animal
has jackson annotations that help ObjectMapper
(de)serialize the classes. Anyone who extends Animal
will have to edit only annotations present on Animal
to make sure (de)serialization works as intended leaving the class untouched.
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
// all subclasses
@Type(value = Dog.class, name = "dog")
})
public abstract class Animal {
// fields, constructors, getters and setters
}
public class Dog extends Animal {
}
Theoretical point of view
Open/closed principle like the whole SOLID is Utopia
. We should continually upgrade our code in that direction but probably we will never end up there because this is not possible. Let's read below articles to see how classical getters
and annotation
constructs can be debatable.
Practical point of view
Like every practical programmer I like to use good tools to solve problems instead of implementing something new myself. When I am asked to serialise given model to JSON
files I am checking whether it is:
- Open-source
- Fast
- Under active development
- It is easy to use
When we are talking about Jackson
and it's annotations, I think, we can find golden middle way between theory and practice. And this is thanks to MixIn
feature. You can separate model from the way how it is serialised to JSON
. Of course when you add new class which extends base class you need to change MixIn
interface
with annotations but this is a price we need to pay.
Edit or Why I forgot to answer a question?
Sorry, I forgot to answer a question whether above example violates Open/Closed principle
or not. First, get definition from Wikipedia
article:
A class is closed, since it may be compiled, stored in a library, baselined, and used by client classes. But it is also open, since any new class may use it as parent, adding new features. When a descendant class is defined, there is no need to change the original or to disturb its clients.
Above example violates When a descendant class is defined, there is no need to change the original
part. Even if we use MixIn
there is a need to change other part of app. Even more, if your solution uses annotations
in 99.99% of cases you violate this part because there is a need to configure somehow functionality which is hidden behind them.