Yapıcı (Builder) Tasarım Şablonu, Factory Pattern(Fabrika şablonu) ve Abstract Factory Pattern(Soyut Fabrika şablonu) gibi Oluşturucu Tasarım Şablonlarından (Creational Desing Pattern) birisidir.
Bu şablon, Fabrika tasarım şablonundaki sorunları çözmeye yöneliktir. Eğer nesne bir çok nitelik (property) içeriyorsa oluşturucu şablon kullanmak uygundur. Aşağıdaki örnekde neden kullanıldığını daha iyi anlayacaksınız.
Bu şablonu uygulamak için yapılması gerekenler
- İlk önce, statik iç içe geçmiş bir sınıf oluşturup, tüm bağımsız değişkenleri dış sınıftan Oluşturucu sınıfına kopyalamanız gerekir. Adlandırma kuralına uymalıyız ve eğer sınıf adı Computer ise, oluşturucu sınıfının adı ComputerBuilder olmalıdır.
- Oluşturucu sınıfının gerekli özellikleri parametre olarak içeren bir public yapılandırıcıya(constructor) sahip olması gerekir.
- Oluşturucu sınıfı, isteğe bağlı parametreleri ayarlamak için yöntemlere sahip olmalıdır ve isteğe bağlı özellikleri ayarladıktan sonra aynı Oluşturucu nesnesini döndürmelidir.
- Son adım oluşturucu sınıfında, istemci tarafından ihtiyaç duyulan nesneyi döndürecek bir build() yöntemi sağlamaktır.
Uygulama Örneği
Diyelim ki, User sınıfımız olsun ve bunun dört tane özelliği olsun. Sınıfınızdaki bazı özelliklerin gerekli olduğunu hayal edin; bazıları ise isteğe bağlıdır.
1 2 3 4 5 6 7 8 9 |
public class User{ private String adi; // zorunlu(required) private String soyadi; // zorunlu(required) privata String email; // isteğe bağlı(optional) private String gsmNo; // isteğe bağlı(optional) ... } |
Bu sınıftan nesne oluşturmak istediğimizde zorunlu olan iki özellik için bir yapılandırıcı(constructor) yapmak ve diğer özellikler içinde bu constructor’u overload etmek zorunda kalacağız.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public User(String adi, String soyadi) { this(adi, soyadi, ""); } public User(String adi, String soyadi, String email){ this(adi, soyadi, email, ""); } public User(String adi, String soyadi, String email, String gsmNo){ this.adi = adi; this.soyadi = soyadi; this.email = email; this.gsmNo = gsmNo; } |
Yalnızca birkaç özellik(property) olduğunda büyük sorun teşkil etmeyebilir, ancak özellik sayısı arttıkça kodun okunması ve bakımı daha zorlaşır. Daha da önemlisi, bu sınıfı kullanacak diğer kişiler için gittikçe zorlaşıyor. Hangi yapılandırıcıyı(constructor) çağırayım? İki parametre olanı mı ? Üç parametre olanı mı ? Elimde email yok gsmNo varsa hangisi ile nesne oluşturmayalım ???
Peki bu aşama da ne yapabiliriz ? Zorunlu olan iki parametre için bir constructor ve diğer parametreler için getter-setter koyarak sınıfımızı tasarlayabiliriz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public User(String adi, String soyadi) { this.adi = adi; this.soyadi = soyadi; } public String getAdi() { return adi; } public void setAdi(String adi) { this.adi = adi; } public String getSoyadi() { return soyadi; } public void setSoyadi(String soyadi) { this.soyadi = soyadi; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getGsmNo() { return gsmNo; } public void setGsmNo(String gsmNo) { this.gsmNo = gsmNo; } |
Bu yaklaşım, okuması ve bakımı daha kolay görünüyor. Bir istemci(client) olarak zorunlu iki parametreli bir nesne oluşturabilir ve daha sonra yalnızca ilgilendiğim özellikleri ayarlayabilirim.
Peki bunun nesi var? Bu çözümün iki ana sorunu vardır;
- Sınıfın sahip olduğu tüm dört özellik için değerleri olan bir User nesnesi oluşturmak istiyorsanız, nesnenin, tüm setter yöntemleri çağrılıncaya kadar tam bir duruma sahip olmayacaktır.
- Artık sınıf tamamiyle dışarı açıldı ve Kullanıcı nesnenin tüm özellikleri değiştirilebilir şekildedir.
Tam bu haldeyken, Yapıcı (Builder) tasarım şablonu çıkıyor. Benim isteğim sadece bana istediğim özelliklerle User nesnesi yaratmak başka hiç bir müdahele yapamamalıyım. Adından da belli sadece oluştur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
public class User { private String adi; // required private String soyadi; // required private String email; // optional private String gsmNo; // optional private User(UserBuilder builder) { this.adi = builder.adi; this.soyadi = builder.soyadi; this.email = builder.email; this.gsmNo = builder.gsmNo; } public String getAdi() { return adi; } public String getSoyadi() { return soyadi; } public String getEmail() { return email; } public String getGsmNo() { return gsmNo; } public static class UserBuilder { private String adi; private String soyadi; private String email; private String gsmNo; public UserBuilder(String adi, String soyadi) { this.adi = adi; this.soyadi = soyadi; } public UserBuilder email(String email) { this.email = email; return this; } public UserBuilder gsmNo(String gsmNo) { this.gsmNo = gsmNo; return this; } public User build() { return new User(this); } } } |
Test Sınıfı
1 2 3 4 5 6 |
public class BuilderTest { User user = new User.UserBuilder("Koray", "Peker") .email("koraypeker1453@hotmail.com").build(); } |
Java’da Örnekleri :
- java.lang.StringBuilder#append() (unsynchronized)
- java.lang.StringBuffer#append() (synchronized)
2 yorum yapıldı “Yapıcı (Builder) Tasarım Şablonu”