Lombok でできること確認します。( @Builder )

2021年5月6日

この記事では Lombok の @Builder について確認したいと思います。

長いコンストラクタ

下記のコードを見てください。

package com.example.demo;

public class HogeLombok {
	private int age;
	private String name;
	private String tokugi;
	private String hobby;
	private String school;
	private int opt01;
	private int opt02;

	
	/**
	 * ながーーーーーーーーーーいコンストラクタ
	 * 
	 * @param age
	 * @param name
	 * @param tokugi
	 * @param hobby
	 * @param school
	 * @param opt01
	 * @param opt02
	 */
	public HogeLombok(int age, String name, String tokugi, String hobby, String school, int opt01, int opt02) {
		this.age = age;
		this.name = name;
		this.tokugi = tokugi;
		this.hobby = hobby;
		this.school = school;
		this.opt01 = opt01;
		this.opt02 = opt02;
	}
}

恐ろしく引数が多いメソッド(コンストラクタ)です。
このクラスを使うには当然すべての引数に枠に値を格納してあげないといけません。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
		
		// インスタンス化!(ひぃぃぃぃぃ!)
		HogeLombok v = new HogeLombok(0, null, null, null, null, 0, 0);
				
		System.out.println("v " + v);
	}
}

この部分だけみて、何のため引数かわかるでしょうか?

HogeLombok v = new HogeLombok(0, null, null, null, null, 0, 0);

わたしは頭が弱いので目が回りそうになってしまいます。

こうしてみよう!

渡す値の前にコメントを付与してなんの値なのかわかりやすくしてみました!

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
		
		// インスタンス化!(ひぃぃぃぃぃ!)
		HogeLombok v = new HogeLombok(/*age=*/0, /*name=*/null, /*tokugi=*/null, /*hobby=*/null, /*school=*/null, /*opt01=*/0, /*opt02=*/0);
				
		System.out.println("v " + v);
	}
}

・・・値の意味は分かるようになりましたが一行が長い😣

お仕事ではどうなの?

お仕事ではコーディングルールという実装のルールがあったりします。
ちゃんとしているところだとこういった引数をたくさんとるメソッドはNGになったりもします。

可読性が低いと不具合を誘発する要因となりますからね。

ビルダー

この問題の解決方法は(呼び出し元でコメントを付与するという対応含め)いくつかあると思います。
こちらの記事が大変参考になります。

Lombok ではこの問題を ビルダーという機能で解決します。その名も @Builder です。

試してみよう

ともあれ実際に試してみようと思います。

package com.example.demo;

import lombok.Builder;
import lombok.ToString;

@ToString
@Builder
public class HogeLombok {
	private int age;
	private String name;
	private String tokugi;
	private String hobby;
	@Builder.Default private String school = "デフォルト高校";	// デフォルト値を変更することも可能
	private int opt01;
	private int opt02;
	
	/**
	 * ClassName+Builder でデフォルト値の指定が可能です。
	 */
	public static class HogeLombokBuilder {
		private int opt02 = -100;
	}
}

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
		
		// インスタンス化!
		HogeLombok v = HogeLombok.builder()
				.age(100)
				.name("太郎")
				.tokugi("柔道")
				.build();
				
		System.out.println("v " + v);
	}
}

@Builder.Defaultをフィールドに指定すると、初期値を指定することができます。
まあ、 クラス名 + Builder という名前で静的なクラスを作成しフィールドを実装しても同様に初期値を指定することができます。

@ToStringは便宜的に付与しています。今回の @Builder の機能とは関係ありません。

確認

では実行してみましょう。

schoolとopt02の値に注目してください。
それぞれあらかじめ指定しておいた値が出力されていますね。

そのほかの指定しなかった変数は書く型の初期値が出力されています。

まとめ

Lombok の @Builder について確認しました。

この機能を使用すればながーーーーいコンストラクタを定義しなくても済みます。
可読性も高まり設定を省略した場合の実装もちゃんと用意してあるなんて素敵な機能です😄

今日はここまで!