Java hibernate : What would be the better design to get rid of casting

标签 java hibernate casting visitor-pattern

我使用 Hibernate 来实现持久性。

假设我有一个实体,其中包含有关文档的信息以及生成文档的必要信息(打印或通过电子邮件发送)。像这样: enter image description here

这里的问题是 DocumentInformation 持有对抽象类 DocumentProductionConfiguration 的引用,而不是对子类 DocumentPrintConfiguration 或 DocumentEmailConfiguration 的引用。

因此,当我实际上需要获得适当的配置时,我有两个选择:要么使用instanceof +强制转换,要么使用访问者模式来欺骗Java,以便它在运行时真正理解它正在处理哪个配置。

  1. 使用转换:

    public class XmlBuilder{
    public XMLMessage buildXmlMessage(DocumentInformation documentInformation){
        if(documentInformation.getDocumentProductionConfiguration() instanceOf DocumentPrintConfiguration){
            DocumentPrintConfiguration printConfig = (DocumentPrintConfiguration) documentInformation.getDocumentProductionConfiguration();
            XMLMessageConfig xmlConfig = handlePrintConfig(printConfig);
        }
     }
     public XMLMessageConfig handlePrintConfig(DocumentPrintConfiguration printConfig){
        ....build that XMLMessageConfig....
     }
    }
    
  2. 使用访问者模式:

我需要添加一个新的接口(interface)供 XmlBuilder 实现

public interface XmlBuilderVisitor<T> {
    T handlePrintConfig(DocumentPrintConfiguration printConfig);
}
public class XmlBuilder implements XmlBuilderVisitor<XMLMessageConfig> {
    @Override
    public XMLMessageConfig handlePrintConfig(DocumentPrintConfiguration printConfig){
        ....build that XMLMessageConfig....
     }
    public XMLMessage buildXmlMessage(DocumentInformation documentInformation){
        XMLMessageConfig xmlMessageConfig = documentInformation.getDocumentProductionConfiguration().buildConfiguration(this);
    }
}
public abstract class DocumentProductionConfiguration{
    public abstract <T> T buildConfiguration(XmlBuilderVisitor<T> visitor);
}
public class DocumentPrintConfiguration extends DocumentProductionConfiguration{
    public <T> T buildConfiguration(XmlBuilderVisitor<T> visitor){
        return visitor.handlePrintConfig(this);
    }
}

这两个解决方案都有点无聊...第一个是因为它违反了开闭原则(我需要始终维护这些 ifs...)。

从这个意义上来说,第二个更好:一旦添加新配置,编译器将引导您完成该过程:首先,您需要在配置本身中实现适当的方法,然后在所有访问者类中实现。另一方面,我基本上将服务传递给实体,这非常尴尬......

所以我觉得我是在治疗症状而不是问题。也许设计本身需要一些改变?但我不确定如何改进......

最佳答案

我建议将“句柄”功能插入 DocumentProductionConfiguration 和子类中。这样 DocumentPrintConfiguration 将包含一个 handle 函数,该函数构建并返回 XMLMessageConfig。那么你的 XmlBuilder 就变成:

public class XmlBuilder{
    public XMLMessage buildXmlMessage(DocumentInformation documentInformation){
        XMLMessageConfig xmlConfig = documentInformation.getDocumentProductionConfiguration().handle();
    }
}

关于Java hibernate : What would be the better design to get rid of casting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40683053/

相关文章:

java - 如何在 Kotlin 中检查数组类型(不是泛型类型)

java - java接口(interface)中的变量

java - 将 JAR 文件转换为可执行文件是否可以确保其分发?

java - 调用 Java Fx ActionEvent 中的方法

java - 因 IllegalArgumentException 导致在 tomcat 中启动 war 失败

java - 在 Hibernate3 中的 saveOrUpdateAll 情况下,具有相同标识符值的不同对象已与 session 关联

java - hibernate LazyInitializing 悖论

java - 如何使用 spring 和 hibernate 将值插入到多个表中

将 Char 缓冲区转换为短裤数组

c++ - 如何将 Windows SOCKADDR_BTH 的 C++ 转换复制到 Rust 中的 SOCKADDR?