liveBook · Manning

Boilerplate code

As explained in The Art of Code

Boilerplate code is repetitive supporting code required by a language, framework, or implementation pattern rather than by distinctive application behavior.

Boilerplate code is repetitive supporting code required around simple data rather than distinctive application behavior. Encapsulation can protect fields while burying their meaning under constructors, getters, setters, and other maintenance-heavy scaffolding. section 4.1.2

A small class with a large maintenance surface

A two-field Person class can require private fields, multiple constructors, getters, setters, equality methods, hashing, string conversion, and builder machinery. Adding or renaming one field then spreads changes across this supporting code, increasing refactoring risk. A builder improves construction readability, while Lombok can generate much of the implementation. section 4.1.2

Listing 4.1 The Person DTO written with full boilerplate code
public class Person {
  private String firstname;
  private String lastname;

  public Person() {}                 #1
                                     #1
  public Person(                     #1
     String firstname,               #1
     String lastname) {              #1
    this.firstname = firstname;      #1
    this.lastname = lastname;        #1
  }                                  #1

  public void setLastname(String lastname) {      #2
    this.lastname = lastname;                    #2
  }                                              #2

  public void setFirstname(String firstname) {   #2
    this.firstname = firstname;                  #2
  }                                              #2

  public String getFirstname() {       #3
    return firstname;                 #3
  }                                   #3

  public String getLastname() {       #3
    return lastname;                  #3
  }                                   #3


  @Override                                               #4
  public String toString() {                   #4           
    return "Person{" +                         #4           
       "firstname='" + firstname + '\'' +      #4           
       ", lastname='" + lastname + '}';        #4           
  }                                            #4 
                                               #4 
  @Override                                    #4           
  public boolean equals(Object o) {            #4           
    if (this == o) return true;                #4           
    if (!(o instanceof Person person))         #4          
      return false;                            #4          
    return Objects.equals(firstname, person.firstname)    #4
       && Objects.equals(              #4           
       lastname,                               #4   
       person.lastname);                       #4   
  }                                            #4  
                                               #4
  @Override                                    #4  
  public int hashCode() {                      #4  
    return Objects.hash(firstname, lastname);  #4  
  }                                            #4          

  private Person(Builder builder) {                     #5
    this.firstname = builder.firstname;                 #5
    this.lastname = builder.lastname;                   #5
  }                                                     #5
                                                        #5
  public static class Builder {                         #5
    private String firstname;                           #5
    private String lastname;                            #5
                                                        #5
    public Builder setFirstname(String firstname) {     #5
      this.firstname = firstname;                       #5
      return this;                                      #5
    }                                                   #5
                                                        #5
    public Builder setLastname(String lastname) {       #5
      this.lastname = lastname;                         #5
      return this;                                      #5
    }                                                   #5
                                                        #5
    public Person build() {                             #5
      return new Person(this);                          #5
    }                                                   #5
  }                                                     #5
} #5

Inspect the verbose Person DTO to see how simple data becomes surrounded by constructors, accessors, and other supporting methods. section 4.1.2

Person p = Person.builder().firstname("John")
                 .lastname("Doe")
                 .town("Grenoble")
                 .build();

Compare the explicit builder calls with positional construction to see how a construction API can make selected fields and intent easier to read. section 4.1.2

Use the following heuristics when supporting code begins to outweigh the data it serves:

  • Prefer concise immutable data carriers when the language provides them, including Java records, Kotlin data classes, C# records, or Python dataclasses. section 4.4
  • Treat boilerplate as a clarity and maintenance concern, not merely a line-count problem: generic supporting code can obscure intent and become a source of bugs. section 4.1.2

How The Art of Code covers it

How deep it goes
Quantifies boilerplate with a Person example and a line-count estimate, then points to builders and concise data constructs.
Examples
Uses a Java Person DTO, overloaded constructors, accessors, a builder, Lombok, and concise record-like data carriers.
What it assumes
Assumes familiarity with Java classes and encapsulation while contrasting traditional data classes with newer concise constructs.
What you can do after
Evaluate when supporting code obscures data intent and choose builders, generation, or concise data constructs to reduce it.
How it connects
Connects boilerplate code to encapsulation, the Builder pattern, mutable data, immutability, and data modeling.

Also explained in

Compare how 2 books explain boilerplate code →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Art of Code. The section links point to the parts of the book it draws on.