java - 如何将面向对象的结构映射到表单字段?

标签 java xml oop groovy pdfbox

我创建了一个面向对象的结构,其中包含 Header、Address、Subject、DetailedItem 等类。每个类都有不同类型的字段:

public class Address {
    private String countryCode;
    private String voivodeship;
    private String county;
    private String community;

    // more fields, constructors, getters & setters..
}

public class Subject1 {
    private NonPhysicalPerson nonPhysicalPerson;
    private PhysicalPerson physicalPerson;

    // more fields, constructors, getters & setters..
}

我有一个 PDF 表格,其中包含某项内容。约100个字段。每个字段由ID表示:

  • 对于 PDF 的页眉部分:h1、h2、...、hn
  • 对于 PDF 的主题 1 部分:s1、s2、...、sn
  • 对于 PDF 的主题 2 部分:t1、t2、...、tn
  • PDF 的详细信息部分:d1、d2、...、dn

我有一个问题。我不知道如何将这些字段映射到表单 ID。我只是想避免做类似的事情(我有特殊的类字段,其中包含每个表单字段的数据 - 我的意思是对于“h4”我必须使用 getOne() ,对于“h5”getSthDifferent() 等):

    List<PDField> fields = acroForm.getFields();
    for (PDField field : fields) {
        String fieldName = field.getFullyQualifiedName();

        // branching like that would be terrible
        if (fieldName.equals("h1")) {
            field.setValue(header.getFormCode());
        } else if (fieldName.equals("h2")) {
            field.setValue(header.getFormVariant());
        } else if (fieldName.equals(...)) {
            // etc...
        } else if (fieldName.equals("d43")) {
            field.setValue(detailedItem.getDetailsMap().getKey("d43"));
        } 
    }

有什么方法可以优雅地做到这一点(任何设计模式或只是棘手的想法)? 我正在使用 Java、Groovy + PDFBox。

感谢您的帮助!

编辑(我的解决方案)

作为指定表单部分的面向对象表示的每个类,现在都实现 List<String> getData() 接口(interface)方法。我将类字段值添加到 List<String> data然后在顶级类List<String> data中添加All对于每个部分:

    data.addAll(header.getData());
    data.addAll(subject1.getData());
    data.addAll(subject2.getData());
    data.addAll(details.getData());

在我的情况下,字段的顺序始终保持不变,因此我能够仅在一个 for 中正确填写数据环形。我认为我的实现对于我的目的来说足够灵活。另外 for 循环看起来像:

    for (int i = range.getStartIndex(); i < range.getEndIndex(); i++) {
        fields.get(i).setValue(data.get(i));
    }

哪里startIndexendIndex是每个部分的界限,因此我可以选择准备填充的部分。

也许我的解决方案不是最干净的选择(+我们必须牢记性能,因此将来需要优化),但它很容易修改。我希望它能对某人有所帮助。

最佳答案

不要将 PDFField 视为愚蠢的对象/数据集合

您在 field's name 之间有直接关联和the way you set the field's value ,这可能表明您的架构存在问题。

封装 switch 的类(我们称之为类 A )太关心你的 PDFField对象(它询问了太多有关字段内部数据的问题并改变了它的状态)。

您对待PDFField作为数据集合,而不是作为对象(知道如何处理其内部状态)<-- 我无法帮助您解决此问题,因为我无法查看整体代码源。

避免该切换的可能解决方案

您可以使用字典 Dictionary<String, Consumer<PDFFiled>>(key, value) = ("string", (field) -> field.setValue(/*value*/))

...并且您使用 key (字段名称)询问用户,并与用户一起接受归档。 fields.forEach(field -> dict.get(filed.getName()).accept(filed)

不是一个好的解决方案!您将避免这种切换,但代码仍然难以维护(难以扩展、难以更改等)。

其他说明

在您的情况下,您不能使用设计模式 Strategy , Chain of responsibility , Decorator , Factory因为您不能仅仅为了封装一行更改字段值的代码而创建 100 多个类。

关于java - 如何将面向对象的结构映射到表单字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47730647/

相关文章:

php - 无法从子对象访问父变量

java - 如何改进 WebDriver ExpectedCondition 的错误消息?

xml - 当存在特殊字符时,Saxon 中的 CSV 到 XML 转换失败

java - 用java解析http返回的xml

oop - 类是面向对象语言中的对象吗

php - PHP 接口(interface)有属性吗?

java - 如何在 Java Play Framework 中在一周中的特定一天运行 akka 调度程序?

java - 方法存在时抛出 NoSuchMethodException

java - 从 BufferedImage 到文件 : Return Type issues

xml - 使用 PowerShell 将 xml 从 UTF-16 转换为 UTF-8