Java 此代码是否违反开闭原则?
我想知道下面的代码是否违反了开闭原则Java 此代码是否违反开闭原则?,java,oop,design-patterns,jackson,jackson-databind,Java,Oop,Design Patterns,Jackson,Jackson Databind,我想知道下面的代码是否违反了开闭原则 Animal是Dog的父类,但是Animal具有帮助ObjectMapper(反)序列化类的jackson注释。任何扩展Animal的人都必须只编辑Animal上的注释,以确保(反)序列化按预期工作,保持类不变 @JsonTypeInfo( use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property=“type”) @JsonSubTypes({ //所有子类 @类型(value=
Animal
是Dog
的父类,但是Animal
具有帮助ObjectMapper
(反)序列化类的jackson注释。任何扩展Animal
的人都必须只编辑Animal
上的注释,以确保(反)序列化按预期工作,保持类不变
@JsonTypeInfo(
use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY,
property=“type”)
@JsonSubTypes({
//所有子类
@类型(value=Dog.class,name=“Dog”)
})
公共抽象类动物{
//字段、构造函数、getter和setter
}
公家犬{
}
理论观点
就像整个乌托邦一样。我们应该不断地朝这个方向升级我们的代码,但我们可能永远不会达到这个目的,因为这是不可能的。让我们阅读下面的文章,看看经典的getter
和annotation
构造是如何有争议的
实践观点
像每一个实际的程序员一样,我喜欢使用好的工具来解决问题,而不是自己实现新的东西。当我被要求将给定模型序列化到JSON
文件时,我正在检查它是否:
JSON
的方式分开。当然,当您添加扩展基类的新类时,您需要使用注释更改MixIn
接口,但这是我们需要付出的代价
编辑或为什么我忘记回答问题?
对不起,我忘记回答一个问题,上面的例子是否违反了打开/关闭原则。首先,从以下方面获取定义:
类是封闭的,因为它可以被编译、存储在库中,
基线化,并由客户端类使用。但它也是开放的,因为任何
新类可以将其用作父类,从而添加新功能。当一个后代
类已定义,无需更改原始或
打扰客户
上面的示例违反了定义子类时,不需要更改原始的部分。即使我们使用MixIn
也需要更改应用程序的其他部分。更重要的是,如果您的解决方案在99.99%的情况下使用注释,那么您违反了此部分,因为需要以某种方式配置隐藏在注释后面的功能。确实如此。开闭原理的思想是使对象可以扩展,而不必在内部修改它们。由于动物的任何新子类都必须对其进行修改才能正常工作,因此它违反了原则。打开/关闭意味着类应打开以进行扩展,但关闭以进行修改
换句话说。。。如果你想改变一个类的行为,你应该以某种方式扩展它,但不应该修改它
你可以通过
- 创建一个子类。这通常使用模板方法模式来完成
- 定义类A使用的接口,以便通过向其传递该接口的另一个实例(例如,策略模式)来扩展其行为。一个很好的现实例子是A,因为它的排序行为可以在不修改
TreeSet
本身的情况下更改
在我看来,@JsonSubTypes
注释不是动物
类行为的一部分。它改变了另一个类——对象映射器的行为。因此,这不是真正的违反。不是真的意味着即使你不改变行为,你也必须触摸Animal
类并重新编译它
这是一个非常奇怪的注释设计。为什么json开发人员不允许您在子类上添加注释,例如JPA在涉及层次结构映射时所做的那样。看
超类型引用子类型是一种奇怪的设计。
抽象类型不应该依赖于具体类型。在我看来,这是一个应该始终应用的原则。对不起,我忘记回答这个基本问题,因为在我看来,从理论角度来看:违反,从实践角度来看:不,因为成本不高。但是每个人都应该自己定义成本
。谢谢您的编辑!除了MixIn
之外,还有另一种解决方案@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”)公共抽象类Animal{//fields,constructor,getter和setters}@JsonTypeName(value=“Dog”)公共类Dog从相同的维基百科
扩展Animal{}
:“一个模块如果[它]可供其他模块使用。这假设已为该模块提供了定义良好、稳定的描述”。此解决方案不是定义良好的和稳定的
,因为您可以从根中删除JsonTypeInfo
注释,所有子体将突然中断。不能强制子体具有此注释,也不能强制根类具有此注释,因为接口/类未断开。它包含相同的方法<代码>API
是相同的,但有些东西不起作用。有超过50%的问题是关于的,所以
。我同意SOLID code是应许之地。我同意我们应该努力做到这一点。我不同意这是不可能的。@aridlehoover,当我写不可能时
我指的是整个项目。当然,我们可以在SOLID
模式下实现项目的某些部分,但整个项目是n