Builder Kalıbı
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 67 / 87.
Builder Deseni, yaygın bir sorunu çözen, nesne oluşturmaya yönelik (creational) bir tasarım desenidir: birçok isteğe bağlı parametreye sahip karmaşık nesnelerin oluşturulması. Birden fazla yapıcı (constructor) oluşturmak veya kullanılmayan parametreler için null geçmek yerine, Builder nesneleri adım adım oluşturmanıza olanak tanır.
Gerekli alanlara (name, email) ve isteğe bağlı alanlara (age, phone, address) sahip bir User nesnesi oluşturmayı düşünün. Bir Builder olmadan, teleskopik yapıcılara veya çok sayıda parametreye sahip karmaşık bir yapıcıya ihtiyaç duyarsınız. Builder deseni daha temiz bir yaklaşım sunar:
public class User {
private final String name; // zorunlu
private final String email; // zorunlu
private final int age; // isteğe bağlı
private final String phone; // isteğe bağlı
private User(UserBuilder builder) {
this.name = builder.name;
this.email = builder.email;
this.age = builder.age;
this.phone = builder.phone;
}
public static class UserBuilder {
private final String name;
private final String email;
private int age;
private String phone;
public UserBuilder(String name, String email) {
this.name = name;
this.email = email;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public User build() {
return new User(this);
}
}
}Builder metotları this döndürerek, nesne oluşturmak için akıcı ve okunabilir bir yol olan metot zincirlemeyi (method chaining) mümkün kılar:
User user = new User.UserBuilder("Alice", "alice@email.com")
.age(25)
.phone("555-1234")
.build();User kurucusunun private olduğuna dikkat edin; nesneler yalnızca Builder aracılığıyla oluşturulabilir. Bu desen, nesnelerin çok sayıda isteğe bağlı alanı olduğunda parlar ve kodunuzu uzun parametre listelerine kıyasla daha okunabilir ve hataya daha az açık hale getirir.
Görev
KolayBuilder Pattern kullanarak bir pizza sipariş sistemi oluşturalım! Tüm olası malzemeler ve seçenekler için düzinelerce parametre alan bir yapıcı (constructor) ile uğraşmak yerine, pizza özelleştirmesini temiz ve okunabilir hale getiren akıcı bir builder oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
Pizza.java: Oluşturma işlemi için Builder Pattern kullanan birPizzasınıfı oluşturun. Pizzanız şu alanlara sahip olmalıdır:size(String) - zorunlu, pizza boyutunu temsil edercheese(boolean) - isteğe bağlı, varsayılan olarak falsepepperoni(boolean) - isteğe bağlı, varsayılan olarak falsemushrooms(boolean) - isteğe bağlı, varsayılan olarak falsePizzayapıcısı private olmalı ve parametre olarak yalnızca birPizzaBuilderkabul etmeli, builder'daki tüm değerleri pizzanın alanlarına kopyalamalıdır.Şu formatta bir dize döndüren bir
getDescription()metodu ekleyin:[size] Pizza with: [toppings]; burada toppings, true olan malzemelerin (Cheese, Pepperoni, Mushrooms) virgülle ayrılmış bir listesidir. Hiçbir malzeme seçilmemişse, malzemeler kısmı sadeceno toppingsdemelidir.Şunları içeren bir statik iç sınıf (inner class)
PizzaBuilderoluşturun:- Gerekli
sizeparametresini alan bir yapıcı - Her biri ilgili boolean değerini true olarak ayarlayan ve zincirleme kullanım (chaining) için
thisdöndürencheese(),pepperoni()vemushrooms()metodları - Yeni bir
Pizzadöndüren birbuild()metodu
- Gerekli
Main.java: Pizza builder'ınızı iş başında gösterin! Dört girdi alacaksınız: pizza boyutu (String) ve sırasıyla peynir, pepperoni ve mantar eklenip eklenmeyeceğini belirten üç adet yes/no değeri (String).Verilen boyuta sahip bir
PizzaBuilderoluşturun. Ardından, her bir yes/no girdisine göre uygun malzeme metodlarını zincirleyin. Eğer girdi"yes"ise, o malzeme metodunu çağırın;"no"ise atlayın. Son olarak, pizzanızı oluşturmak içinbuild()metodunu çağırın.Tamamlanan pizzanız üzerinde
getDescription()metodunu çağırmanın sonucunu yazdırın.
Sırasıyla dört girdi alacaksınız: boyut (String), peynir ekle (String: "yes" veya "no"), pepperoni ekle (String: "yes" veya "no"), mantar ekle (String: "yes" veya "no").
Örneğin, Large, yes, no, yes girdileriyle çıktınız şöyle olacaktır: Large Pizza with: Cheese, Mushrooms
Builder Pattern'in, her olasılık için ayrı yapıcılara ihtiyaç duymadan herhangi bir malzeme kombinasyonuyla pizza oluşturmanıza nasıl olanak tanıdığına dikkat edin!
Kopya kağıdı
Builder Deseni, çok sayıda isteğe bağlı parametreye sahip karmaşık nesneleri oluşturmak için kullanılan yaratımsal bir tasarım desenidir. Nesneleri adım adım inşa ederek iç içe geçmiş (telescoping) kuruculardan ve uzun parametre listelerinden kaçınmayı sağlar.
Yapı
Desen şunlardan oluşur:
- Sadece bir builder kabul eden özel bir kurucuya (private constructor) sahip bir sınıf
- Nesneyi inşa eden statik bir dahili Builder sınıfı
- Metot zincirleme (method chaining) için
thisdöndüren Builder metotları - Nihai nesneyi oluşturan bir
build()metodu
Uygulama Örneği
public class User {
private final String name; // zorunlu
private final String email; // zorunlu
private final int age; // isteğe bağlı
private final String phone; // isteğe bağlı
private User(UserBuilder builder) {
this.name = builder.name;
this.email = builder.email;
this.age = builder.age;
this.phone = builder.phone;
}
public static class UserBuilder {
private final String name;
private final String email;
private int age;
private String phone;
public UserBuilder(String name, String email) {
this.name = name;
this.email = email;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public User build() {
return new User(this);
}
}
}Metot Zincirleme ile Kullanım
User user = new User.UserBuilder("Alice", "alice@email.com")
.age(25)
.phone("555-1234")
.build();Builder deseni, nesnelerin çok sayıda isteğe bağlı alana sahip olduğu durumlarda idealdir; çok sayıda parametreye sahip kuruculara kıyasla okunabilir ve bakımı kolay kod sağlar.
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Girdileri oku
String size = scanner.nextLine();
String addCheese = scanner.nextLine();
String addPepperoni = scanner.nextLine();
String addMushrooms = scanner.nextLine();
// TODO: Verilen boyuta göre bir PizzaBuilder oluşturun
// TODO: evet/hayır girdilerine göre malzeme ekleme metotlarını zincirleyin
// TODO: Pizzayı oluşturun ve açıklamasını yazdırın
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıYineleyici Kalıbı