此代码是否违反开闭原则?

Rag*_*ani 5 java oop design-patterns jackson jackson-databind

我想知道以下代码是否违反开放式封闭原则。

Animal是的父类Dog,但是Animal具有杰克逊注释,可帮助ObjectMapper(反)序列化这些类。扩展的任何人Animal都仅需编辑当前存在的注释,Animal以确保(反序列化)按预期工作,而不会影响类。

@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 {

}
Run Code Online (Sandbox Code Playgroud)

Mic*_*ber 0

理论观点

开放/封闭原则就像整个SOLID一样Utopia。我们应该朝这个方向不断升级我们的代码,但可能我们永远不会到达那里,因为这是不可能的。让我们阅读下面的文章,看看经典getters和annotation构造是如何引起争议的。

  1. 打印机代替吸气剂
  2. Java注解是一个大错误

实用的观点

像每个实用的程序员一样,我喜欢使用好的工具来解决问题,而不是自己实现新的东西。当我被要求将给定模型序列化到JSON文件时,我正在检查它是否是:

  1. 开源
  2. 快速地
  3. 正在积极开发中
  4. 它很容易使用

当我们谈论Jackson它的注释时,我认为,我们可以在理论和实践之间找到黄金的中间道路。这要归功于MixIn功能。您可以将模型与其序列化为 的方式分开JSON。当然,当您添加扩展基类的新类时,您需要MixIn interface使用注释进行更改,但这是我们需要付出的代价。

编辑或为什么我忘记回答问题?

抱歉,我忘了回答上面的例子是否违反的问题Open/Closed principle。Wikipedia首先,从文章中获取定义:

类是封闭的,因为它可以被编译、存储在库中、基线化以及由客户端类使用。但它也是开放的,因为任何新类都可以使用它作为父类,添加新功能。当定义了后代类时,无需更改原始类或打扰其客户。

上面的例子违反了When a descendant class is defined, there is no need to change the original部分。即使我们使用MixIn也需要更改应用程序的其他部分。更重要的是,如果您的解决方案annotations在 99.99% 的情况下使用,您就违反了这一部分,因为需要以某种方式配置隐藏在它们后面的功能。