Java Hibernate:什么是更好的设计摆脱铸造

时间:2016-11-18 17:43:02

标签: java hibernate casting visitor

我使用Hibernate进行持久化。

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

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

因此,当我真正需要获得适当的配置时,我有两个选择:使用instanceof + cast或使用访问者模式来欺骗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. 使用访客模式:

  3. 我需要为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 ......)。

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

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

1 个答案:

答案 0 :(得分:0)

我建议将“句柄”功能推送到DocumentProductionConfiguration和子类中。因此DocumentPrintConfiguration将包含构建并返回handle的{​​{1}}函数。然后你的XmlBuilder变成:

XMLMessageConfig