An Intellij plugin to generate a nested static Builder for a Class.
Why another Builder plugin? --------------------------- There were several Builder plugins already out there, but none that generated a Builder that conformed to the pattern laid out in [Effective Java](http://www.informit.com/articles/article.aspx?p=1216151&seqNum=2), which we use extensively. In addition, the [Features](/README.md#features) outlines other goodies.- Download the latest release.
- From Intellij: Preferences -> Plugins -> Install plugin from disk...
- Restart Intellij
- From a Class, right click -> Generate... -> Builder...
- Remove any fields you don't want and select which fields are nullable
- Creates a static nested Builder that conforms to the pattern in Effective Java.
- Select what fields you want to include in the Builder.
- A Guava
Preconditions.checkNotNullwill be added to the constructor for non-null fields. - If
javax.persistenceannotations exist on fields, nullable will be inferred for the UI dialog box. - Can optionally generate getters, which will return an
Optionalif the field is nullable.
publicvoidtestBarThingIsDifferent() {
Barbar1 = ... // complicated construction code with many fieldsbar1.setThing("thing1");
Barbar2 = ... // more construction codebar2.setThing("thing2");
Zenzen = ... // still more setup codeFoofoo1 = newFoo(bar1, zen);
Foofoo2 = newFoo(bar2, zen);
assertSomethingAboutBar(foo1, foo2);
}Now if we use a Builder and write a test fixture method once:
publicclassTestFixtures {
...
publicFoo.BuildernewFooBuilder() {
returnnewFoo.Builder()
.bar(newBar())
.zen(newZen());
}
...
}Now we can reuse the fixture method everywhere and only override exactly what we care about.
publicvoidtestBarThingIsDifferent() {
Barbar1 = testFixtures.newBarBuilder()
.thing1("thing1")
.build();
Barbar2 = testFixtures.newBarBuilder()
.thing2("thing2")
.build();
Foofoo1 = testFixtures.newFooBuilder()
.bar(bar1)
.build();
Foofoo2 = testFixtures.newFooBuilder()
.bar(bar2)
.build();
assertSomethingAboutBar(foo1, foo2);
}Some good things about the new Test:
- We've completely removed the construction of objects we don't care about, like
Zen - It's very clear that
thingis different and that's what we're testing.
The main drawback to using a Builder is the tedious overhead to write one. The fewer dependencies you have, the less inclined you are to write one. But we just argued for a Builder with only 2 depenencies? That's where the plugin comes in! Say you have the given class:
publicclassFoo {
privatefinalBarbar;
privatefinalZenzen; // This can be null.
}With the click of a button you can generate the following code:
publicclassFoo {
privateBarbar;
privateZenzen;
privateFoo(Builderbuilder) {
this.bar = Preconditions.checkNotNull(builder.bar);
this.zen = builder.zen;
}
publicBargetBar() {
returnbar;
}
publicOptional<Zen> getZen() {
returnOptional.ofNullable(zen);
}
publicstaticclassBuilder {
privateBarbar;
privateZenzen;
publicBuilderbar(Barbar) {
this.bar = bar;
returnthis;
}
publicBuilderzen(Zenzen) {
this.zen = zen;
returnthis;
}
publicBuilderfromPrototype(Fooprototype) {
bar = prototype.bar;
zen = prototype.zen;
returnthis;
}
publicFoobuild() {
returnnewFoo(this);
}
}
}