Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

41 Commits

Repository files navigation

Builder plugin for Intellij

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

Use

  • From a Class, right click -> Generate... -> Builder...
  • Remove any fields you don't want and select which fields are nullable

Features

  • 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.checkNotNull will be added to the constructor for non-null fields.
  • If javax.persistence annotations exist on fields, nullable will be inferred for the UI dialog box.
  • Can optionally generate getters, which will return an Optional if the field is nullable.
Why a Builder? -------------- [Effective Java](http://www.informit.com/articles/article.aspx?p=1216151&seqNum=2) already advocates using a Builder when your class has a handful of dependencies. I would take it even further and argue for a Builder when you have 2 or more dependencies. It makes your Tests more readable and easier to construct. Usually a Test might look something like this:
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:

  1. We've completely removed the construction of objects we don't care about, like Zen
  2. It's very clear that thing is 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);
}
}
}

About

Intellij Builder Plugin

Resources

Stars

24 stars

Watchers

4 watching

Forks

Releases

Packages

Contributors

Languages