Apa permasalahan yang diselesaikan oleh Builder Pattern ini ?

Permasalahan intinya adalah bagaimana mengkonstruksi sebuah objek yang rumit dengan cara yang elegan dan fleksibel.

Seberapa rumit sebuah objek ?

Rumit itu relatif. Akan tetapi karena sebuah objek itu terdiri atas attribute and objek lain, maka secara sederhana, sebuah objek rumit itu karena :

  1. Attributenya banyak
  2. Objek lain sebagai bagian dari objek tersebut juga banyak.
  3. Dengan OOP (Object Oriented Paradigm), maka objek akan rumit kalau sudah menerapkan polimorphisme dan inheritance.

Tapi, bukankah membuat objek itu sebenarnya sederhana ?

Iya, kalau attribut nya sedikit atau bagian dari objek lain tidak banyak. Tetapi kalau sudah banyak dan rumit, maka objek itu tidak sederhana lagi. Ya iyaaa laaah…Bambang !

Contoh atribut yang rumit karena banyak attribute :

Misalkan :

Constructor untuk kasus Mobil (dengan penyederhanaan attribute):

public class Mobil {

	private String nomorStnk;
	private String nomorMesin;
	private String nomorRangka;
	private String merekBan;
	private String merekRadio;
	private String merekKacaFilm;

	public Mobil(String nomorStnk, String nomorMesin, String nomorRangka,
               String merekBan, String merekRadio,String merekKacaFilm) {
		super();
		this.nomorStnk = nomorStnk;
		this.nomorMesin = nomorMesin;
		this.nomorRangka = nomorRangka;
		this.merekBan = merekBan;
		this.merekRadio = merekRadio;
		this.merekKacaFilm = merekKacaFilm;
	}
}

Constructor diatas adalah constructor dengan jumlah attribut hanya 6. Sementara kita tahu untuk objek mobil sendiri, banyak attribute yang melekat kepadanya. Seperti tahun pembuatan, harga jual, engine-type, dll. Ada yang tidak wajib, ada yang mesti ada untuk setiap mobil.

Misalkan, nomorMesion, nomorRangka, merekBan adalah atribute wajib untuk semua mobil. Akan tetapi nomorStnk, merekRadio, merekKacaFilm bisa jadi tidak ada, karena tidak semua mobil memiliki radio dan kaca film. Dan belum tentu semua mobil sudah mempunyai STNK, tergantung apakah mobilnya baru, STNK nya sudah mati, dll

Kalau misalnya mobilnya tidak memiliki radio dan tidak memiliki kaca film, akibatnya disisi client akan memanggil constructor dengan passing null value.

Contoh :

Mobil mobil = new Mobil("STNK01","NM908212121","NR87212111", "GOODYEAR", null, null);

nilai null di 2 parameter terakhir adalah nilai untuk merek Radio dan merek Kaca Film.

Kasus lain :

Contoh atribut yang rumit karena banyak objek:

Sebuah objek Mobil, terdiri dari Jumlah Ban, Nomor Mesin, Jumlah Tempat Duduk, Tahun produksi, dll. Hal itu mungkin masih dianggap sederhana.

Akan tetapi kalau ada tambahan lain misalnya aksesoris mobil. Disimpan dalam bentuk List of Key value object. Atau misalkan ada juga tambahan attribute STNK ditambah dengan gambar upload scan an STNK nya, yang dibungkus dalam sebuah objek STNKInfo.

Naah, objek ini sudah mulai rumit. Kita harus menelusuri sampai ke level dalam untuk membuat object nya, kemudian menempelkannya ke objek Mobil.

Seperti code berikut :

public class Mobil {

	private String nomorStnk;
	private String nomorMesin;
	private String nomorRangka;
	private String merekBan;
	private String merekRadio;
	private String merekKacaFilm;
	private List<AksesorisMobil> aksesorisMobils;

	public Mobil(String nomorStnk, String nomorMesin, String nomorRangka,
               String merekBan, String merekRadio,String merekKacaFilm, List<AksesorisMobil> aksesorisMobils) {
		super();
		this.nomorStnk = nomorStnk;
		this.nomorMesin = nomorMesin;
		this.nomorRangka = nomorRangka;
		this.merekBan = merekBan;
		this.merekRadio = merekRadio;
		this.merekKacaFilm = merekKacaFilm;
		this.aksesorisMobils = aksesorisMobils;
	}
}

public class AksesorisMobil {
    private String id;
    private String nama;
}

Daftar Accessories diatas adalah sebuah objek yang mulai rumit. Karena bukan lagi merupakan objek/varible primitive, tetapi merupakan objek tersendiri yang kita harus peduli dengan strukturnya juga.

Bayangkan untuk membuat sebuah objek mobil seperti diatas saja. Berarti akan ada line code khusus untuk membuat List of accesorisMobil, lalu ada line code khusus untuk membuat objek Mobilnya, dan ada line code untuk menempelkan list of AccessorisMobil itu ke objek Mobilnya.

Cukup panjang barangkali ya, karena belum termasuk men-setting attribut-attribut lainnya. Secara logis tidak bermasalah, akan tetapi secara code quality akan kena di bagian brain overload nya, atau bisa juga kesulitan waktu melakukan unit test.

Contoh atribut yang rumit karena banyak objek ditambah polimorphism:

Oke, 2 kasus diatas cukuplah rumit, tapi tidak rumit-rumit amat sih.

Lalu muncul kasus ketiga , yaitu mobil ini ternyata bisa macam-macam tipenya. Bisa saja bertipe mobil biasa, truk (yang mempunyai panjang sumbu, tonase, dan juga jumlah sumbu roda, dll), bus (punya jumlah baris tempat duduk, jumlah penumpang, ada toilet apa tidak, dll)

Dengan bantuan konsep paradigma Objek Oriented, maka kita bisa membuat inheritance dan polimorfisme dari kasus diatas. Dan voallaaaa….hidup akan akan semakin rumit sajaa…

Inheritance dan polimorfisme memang memudahkan dalam men-struktur kan kumpulan objek. Akan tetapi bertambah rumit waktu menganalisa objeknya, atau di waktu menentukan di bagian mana yang boleh di lakukan Inheritance dan Polymorphisme nya ini.

Contoh realnya adakah ?

Tentu saja ada.

Kalau Anda pernah bersinggungan dengan struktur data dalam bentuk JSON yang dikirimkan melalui REST API, maka mungkin Anda pernah melihat struktur JSON yang rumit, terdiri dari banyak node, struktur JSON nya dalam, dan ada inheritance dan polimorfisme di beberapa node atau bahkan di root nya JSON tersebut.

Data yang dikirimkan melalui JSON itu tentunya dibikin dengan cara diassign satu persatu melalui code yang kita buat. Memetakan antara data dan struktur JSON yang kita kirimkan adalah proses yang rumit, yang kalau tidak di desain dengan benar, akan mengacaukan code kita dan juga membuat tidak efektif.

Disinilah salah satu peran dari Builder Pattern.