Does this code violate open-closed principle?

Raghavendra M Dani :

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 {

}
Michał Ziober :

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.

  1. Printers Instead of Getters
  2. Java Annotations Are a Big Mistake

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:

  1. Open-source
  2. Fast
  3. Under active development
  4. 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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=70285&siteId=1