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

时间:2017-12-09 16:29:23

标签: 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的Subject1部分:s1,s2,...,sn
  • 对于PDF的Subject2部分: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()方法的接口。我将类字段值添加到List<String> data,然后在顶级类List<String> data中为每个部分添加addAll:

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

在我的情况下,字段顺序总是不变的,所以我能够在一个for循环中正确填充数据。我认为我的实施足够灵活,符合我的目的。另外对于循环看起来像:

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

其中startIndexendIndex是每个部分的边界,因此我可以选择准备填充的部分。

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

1 个答案:

答案 0 :(得分:0)

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

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

包含switch(让我们称之为类A)的类过于关注你的PDFField对象(它询问有关该字段内部数据的太多问题并改变它的状态)。

你将PDFField视为一个数据集合,而不是一个对象(知道如何使用他的内部状态)&lt; - 我无法帮助你解决这个问题,因为我不能参见整体代码来源。

避免该开关的可能解决方案

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

...并且您要求使用密钥(字段名称)的消费者和您接受提交的消费者。 fields.forEach(field -> dict.get(filed.getName()).accept(filed)

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

其他注释

在您的情况下,您不能将设计模式用作StrategyChain of responsibilityDecoratorFactory,因为您无法创建100多个类以填充一行代码,用于更改字段的值。