太多的样板,我怎样才能减少我的POJO建造者?

时间:2014-09-23 07:11:26

标签: java android design-patterns builder pojo

我有几个使用POJOs的不同builder pattern,但在为每个{@}}添加构建器并生成Object.toStringObject.hashCodeObject.equals后,我的类最终大约有100行代码。必须有一个更好的方法来处理这个问题。我认为拥有一些反思性的建设者会有很多帮助,但我不确定这是不是很好的做法,而且我也不确定我是如何做到这一点的。换句话说,有没有办法实现这样的构建器?

一个简单的POJO:

public class Foo {

    public int id;
    public String title;
    public boolean change;
    ...

}

然后是某种反思建设者:

Foo = ReflectiveBuilder.from(Foo.class).id(1).title("title").change(false).build();

4 个答案:

答案 0 :(得分:4)

也许Project Lombok(是的网站很难看)是你的选择。 Lombok基于注释将代码注入到类中。

使用Lombok,您可以使用@Data注释生成getter,setter,toString()hashCode()equals()

@Data
public class Foo {
    public int id;
    public String title;
    public boolean change;
}

查看@Data documentation section上的示例以查看生成的代码。

Lombok还提供@Builder,为您的班级生成一个构建器。但请注意,这是一个实验性功能:

@Builder
public class Foo {
    public int id;
    public String title;
    public boolean change;
}

现在你可以做到:

Foo foo = Foo.builder()
  .id(123)
  .title("some title")
  .change(true)
  .build();

答案 1 :(得分:4)

简短回答。你要求的是不可能的。 Reflection在运行时查看代码并动态调用方法,它无法生成实际的方法。

你可以做的是:

Foo foo = ReflectiveBuilder.from(Foo.class).
              set("id", 1).
              set("title", "title").
              build();

这有三个大量问题:

  1. 字段为String s - 输入错误导致运行时错误而不是编译时错误
  2. 值为Object s - 错误的类型导致运行时错误而非编译时错误
  3. 它会比替代品慢得多,因为反射很慢。
  4. 所以基于反射的解决方案虽然可行(参见Apache Commons BeanUtils BeanMap)但实际上并不实际。

    很长的答案,如果你愿意允许一些编译时间魔法,你可以使用Project Lombok。 Lombok背后的想法是使用Java注释预处理器系统从注释生成样板代码。

    真正神奇的是所有IDE,至少是大3,理解注释预处理和代码完成仍然能正常运行,即使代码不存在

    对于POJO Builder的情况,您可以使用@Data@Builder

    @Data
    @Builder
    public class Foo {
    
        public int id;
        public String title;
        public boolean change;
        ...
    
    }
    

    @Data注释将生成:

    • 必需的参数构造函数(需要所有final个字段),
    • equalshashCode使用所有字段的方法(可以使用@EqualsAndHashCode注释进行配置)
    • 所有字段上的toString方法(可使用@ToString注释配置
    • public所有字段的getter和setter(可以使用字段上的@Getter / @Setter注释进行配置。)

    @Builder注释将生成一个名为Builder的内部类,可以使用Foo.builder()进行实例化。

    请确保您配置equalshashCodetoString方法,就好像您有两个与Lombok相互引用的类一样,那么您最终会得到一个无限循环在默认情况下,因为这两个类在这些方法中包含另一个。

    还有一个新的configuration system允许您使用,例如,流畅的设置器,因此如果您的POJO是可变的,您可以更少地取消构建器:

    new Foo().setId(3).setTitle("title)...
    

    对于另一种方法,您可以查看Aspect-oriented programming(AOP)和AspectJ。 AOP允许您将课程改为"方面"然后使用预编译器使用某些规则将它们粘在一起。例如,您可以使用自定义注释和方面来实现Lombok的功能。然而,这是一个相当高级的主题,可能会有点矫枉过正。

答案 2 :(得分:1)

我个人使用this网站为我创建POJO的所有样板代码。您需要做的就是粘贴要解析的JSON,它将为您生成所有类。然后我只使用Retrofit来执行信息的请求/缓存/解析。 Here是我的Github帐户中的Retrofit和POJO的示例。 我希望它有所帮助!

答案 3 :(得分:0)

我创建了一个小型库CakeMold来对POJO进行流畅的初始化。它使用反射,当然不是很快。但是在需要编写测试时非常有用。

Person person = CakeMold.of(Person.class)
    .set("firstName", "Bob")
    .set("lastName", "SquarePants")
    .set("email", "sponge.bob@bikinibottom.io")
    .set("age", 22)
    .cook();