Nesne yönelimli programlamada bildiğimiz gibi sınıflar vardır. Sınıftan instance üretirken constructure methodunu kullanırız. Bu method bizden bazen parametre isteyebilir. Buraya kadar bir problem yok. Parametrelerini vererek instance üretebiliriz.
public class Customer{
private String name;
private String surname;
public Customer(String name, String surname) {
this.name = name;
this.surname = surname;
}
}
public void createCustomer(){
Customer cust = new Customer("Ufuk","Ünal");
}
Sorun şu ki projemiz büyüdükçe bu sınıftan instance üretmek için bizden çok fazla parametre isteyebilir. Bu durumda işimize yarayanları yada elimizde olanları gönderip diğerlerini null olarak göndereceğiz. Bir süre sonra bu okunurluğu azaltacak ve gereksiz yere parametre göndermemize neden olacak. Bir diğer sorunda bazı parametreler zorunludur bazıları değildir. Biz bir nesne oluşturduktan sonra zorunlu olan parametreyi null yapamayız. Aynı şekilde nesne oluştururken de zorunlu parametrenin setlenmesi için zorlamalıyız.
public class Customer{
private String name;
private String surname;
private String city;
private String district;
private String street;
public Customer(String name, String surname, String city, String district, String street) {
this.name = name;
this.surname = surname;
this.city = city;
this.district = district;
this.street = street;
}
}
public void createCustomer(){
Customer cust = new Customer("Ufuk","Ünal","İstanbul",null,null);
}
Bu durumu her bir case için farklı farklı constructer oluşturarak çözeriz diyebilirsiniz ancak proje büyüdükçe çok uzun sınıflar oluşmasına ve okunurluğun çok fazla düşmesine neden olacaktır.
public class Customer{
private String name;
private String surname;
private String city;
private String district;
private String street;
public Customer(String name, String surname, String city, String district, String street) {
this.name = name;
this.surname = surname;
this.city = city;
this.district = district;
this.street = street;
}
public Customer(String name, String surname, String city, String district) {
this.name = name;
this.surname = surname;
this.city = city;
this.district = district;
}
public Customer(String name, String surname, String city) {
this.name = name;
this.surname = surname;
this.city = city;
}
public Customer(String name, String surname) {
this.name = name;
this.surname = surname;
}
}
İşte burada karşımıza builder design patern cıkmaktadır. Bu pattern ile bu sorunların her birine çözüm bulabiliyoruz. Bunun yanında final keywordu ile bizim için zorunlu olan alanları constructer içerisinde belirtilmesini zorunlu hale getirdik.
public class Customer {
private final String name;
private final String surname;
private String city;
private String district;
private String street;
public Customer(CustomerBuilder builder) {
this.name = builder.name;
this.surname = builder.surname;
this.city = builder.city;
this.district = builder.district;
this.street = builder.street;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public static class CustomerBuilder {
private final String name;
private final String surname;
private String city;
private String district;
private String street;
public CustomerBuilder(String name, String surname) {
this.name = name;
this.surname = surname;
}
public CustomerBuilder city(String city) {
this.city = city;
return this;
}
public CustomerBuilder district(String district) {
this.district = district;
return this;
}
public CustomerBuilder street(String street) {
this.street = street;
return this;
}
public Customer build() {
return new Customer(this);
}
}
}
Lombok kütüphanesi bu kodları yazmadan, çok basit bir şekilde @Data ve @Builder anotasyonları ile patterni kullanmamızı sağlıyor.
@Builder(builderMethodName = "hiddenBuilder")
@Data
public class Customer {
private final String name;
private final String surname;
private String city;
private String district;
private String street;
public static CustomerBuilder builder(String name,String surname) {
return hiddenBuilder().name(name).surname(surname);
}
}
public static void main(String[] args) {
Customer cust = Customer.builder("Ufuk","Ünal").city("Istanbul").build();
}
Bu kod örneğinde name ve surname alanları doldurulmadan obje oluşmasına izin verilmiyor. Diğerlerine göre ne kadar kısa olduğuna dikkat ediniz.


