Menu
Coddy logo textTech

Builder Kalıbı

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 93 / 104.

Builder deseni, karmaşık bir nesnenin oluşturulmasını temsilinden ayırarak farklı konfigürasyonları adım adım oluşturmanıza olanak tanır. Bu, özellikle bir nesnenin çok sayıda isteğe bağlı parametresi olduğunda veya belirli bir oluşturma sırası gerektirdiğinde kullanışlıdır.

Çok sayıda parametreye sahip bir yapıcı (constructor) yerine (ki bu kafa karıştırıcı hale gelir), Builder her bir yapılandırma seçeneği için net, isimlendirilmiş metotlar sağlar:

#include <iostream>
#include <string>

class Pizza {
public:
    std::string dough;
    std::string sauce;
    std::string topping;
    bool cheese;
    
    void describe() const {
        std::cout << dough << " dough, " << sauce << " sauce, "
                  << topping << (cheese ? ", with cheese" : "") << "\n";
    }
};

class PizzaBuilder {
private:
    Pizza pizza;
    
public:
    PizzaBuilder& setDough(const std::string& d) {
        pizza.dough = d;
        return *this;
    }
    
    PizzaBuilder& setSauce(const std::string& s) {
        pizza.sauce = s;
        return *this;
    }
    
    PizzaBuilder& setTopping(const std::string& t) {
        pizza.topping = t;
        return *this;
    }
    
    PizzaBuilder& addCheese() {
        pizza.cheese = true;
        return *this;
    }
    
    Pizza build() { return pizza; }
};

int main() {
    Pizza margherita = PizzaBuilder()
        .setDough("thin")
        .setSauce("tomato")
        .setTopping("basil")
        .addCheese()
        .build();
    
    margherita.describe();
}

Her bir ayarlayıcı (setter) metodu, oluşturucuya (builder) bir referans döndürür (return *this); bu da akıcı bir arayüz (fluent interface) için metot zincirlemeyi (method chaining) mümkün kılar. build() metodu, oluşturulan nesneyi sonlandırır ve döndürür.

Birçok isteğe bağlı bileşene sahip nesneler oluştururken, okunabilir oluşturma kodu istediğinizde veya aynı oluşturma süreci farklı temsiller oluşturması gerektiğinde Builder kullanın.

challenge icon

Görev

Kolay

Kullanıcıların özel bilgisayarları adım adım yapılandırmasına olanak tanıyan bir Computer Builder (Bilgisayar Oluşturucu) sistemi kuralım. Bu, Builder deseni için mükemmel bir senaryodur; bilgisayarların birçok isteğe bağlı bileşeni vardır ve biz farklı yapılandırmaları birleştirmek için temiz, okunabilir bir yol istiyoruz.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • Computer.h: Tam olarak yapılandırılmış bir bilgisayarı temsil eden ürün sınıfını tanımlayın.

    Computer sınıfınız şu bileşenleri özel (private) üyeler olarak saklamalıdır: cpu (string), ram (string), storage (string), gpu (string) ve hasWifi (boolean). hasWifi değerini varsayılan olarak false, string değerlerini ise boş olarak başlatın.

    Bilgisayarın yapılandırmasını görüntüleyen showSpecs() adında genel (public) bir metot ekleyin. Ayarlanmış olan (boş olmayan string) her bileşen için, onu kendi satırında yazdırın. Wifi özelliği yalnızca etkinleştirilmişse yazdırılmalıdır.

  • ComputerBuilder.h: Akıcı bir arayüz (fluent interface) ile bilgisayarlar inşa eden builder sınıfını oluşturun.

    ComputerBuilder sınıfınızın, inşa ettiği özel bir Computer üyesi olmalıdır. Metot zincirlemeyi (method chaining) etkinleştirmek için her biri builder'a bir referans döndüren şu metotları uygulayın:

    • setCPU(const std::string& cpu)
    • setRAM(const std::string& ram)
    • setStorage(const std::string& storage)
    • setGPU(const std::string& gpu)
    • addWifi() — wifi özelliğini etkinleştirir

    Ayrıca, tamamlanmış Computer nesnesini döndüren ve builder'ı potansiyel yeniden kullanım için sıfırlayan bir build() metodu uygulayın.

  • main.cpp: Özel bir bilgisayar oluşturmak için her şeyi bir araya getirin.

    Dört girdi okuyun:

    1. CPU modeli (string)
    2. RAM özelliği (string)
    3. Depolama özelliği (string)
    4. Wifi dahil edilip edilmeyeceği: yes veya no

    Sağlanan CPU, RAM ve depolama ile bir bilgisayar oluşturmak için ComputerBuilder sınıfını kullanın. Eğer wifi girdisi yes ise, addWifi() metodunu da çağırın. Bu yapılandırmada hiçbir GPU belirtilmediğine dikkat edin; builder isteğe bağlı bileşenleri sorunsuz bir şekilde yönetmelidir.

    İnşa ettikten sonra, yapılandırmasını görüntülemek için sonuçta oluşan bilgisayar üzerinde showSpecs() metodunu çağırın.

showSpecs() metodu şu formatta çıktı vermelidir (yalnızca ayarlanmış bileşenleri göstererek):

CPU: [value]
RAM: [value]
Storage: [value]
GPU: [value]
Wifi: Enabled

Örneğin, Intel i7-12700K, 32GB DDR5, 1TB NVMe SSD ve yes girdileriyle:

CPU: Intel i7-12700K
RAM: 32GB DDR5
Storage: 1TB NVMe SSD
Wifi: Enabled

AMD Ryzen 5 5600X, 16GB DDR4, 512GB SSD ve no girdileriyle:

CPU: AMD Ryzen 5 5600X
RAM: 16GB DDR4
Storage: 512GB SSD

Builder deseninin inşa sürecini nasıl okunabilir ve esnek hale getirdiğine dikkat edin; bileşenleri kolayca ekleyebilir veya atlayabilirsiniz ve metot zincirleme net, kendi kendini belgeleyen bir kod oluşturur. GPU satırı görünmez çünkü onu hiç ayarlamadık, bu da builder'ların isteğe bağlı bileşenleri doğal bir şekilde nasıl yönettiğini gösterir.

Kopya kağıdı

Builder deseni, karmaşık bir nesnenin oluşturulmasını temsilinden ayırarak adım adım yapılandırmaya olanak tanır. Bir nesnenin çok sayıda isteğe bağlı parametresi olduğunda veya belirli bir oluşturma sırası gerektirdiğinde kullanışlıdır.

Çok sayıda parametreye sahip yapıcılar (constructors) yerine Builder, her yapılandırma seçeneği için açık, adlandırılmış yöntemler sunar:

class Pizza {
public:
    std::string dough;
    std::string sauce;
    std::string topping;
    bool cheese;
};

class PizzaBuilder {
private:
    Pizza pizza;
    
public:
    PizzaBuilder& setDough(const std::string& d) {
        pizza.dough = d;
        return *this;  // Metot zincirlemeyi (method chaining) etkinleştir
    }
    
    PizzaBuilder& setSauce(const std::string& s) {
        pizza.sauce = s;
        return *this;
    }
    
    PizzaBuilder& setTopping(const std::string& t) {
        pizza.topping = t;
        return *this;
    }
    
    PizzaBuilder& addCheese() {
        pizza.cheese = true;
        return *this;
    }
    
    Pizza build() { return pizza; }
};

// Metot zincirleme ile kullanım
Pizza margherita = PizzaBuilder()
    .setDough("thin")
    .setSauce("tomato")
    .setTopping("basil")
    .addCheese()
    .build();

Her ayarlayıcı (setter) metot, akıcı bir arayüz (fluent interface) için metot zincirlemeyi etkinleştirmek amacıyla return *this döndürür. build() metodu, oluşturulan nesneyi sonlandırır ve döndürür.

Çok sayıda isteğe bağlı bileşene sahip nesneler oluştururken, okunabilir oluşturma kodları istediğinizde veya aynı oluşturma sürecinin farklı temsiller oluşturması gerektiğinde Builder kullanın.

Kendin dene

#include <iostream>
#include <string>
#include "ComputerBuilder.h"

using namespace std;

int main() {
    // Girdileri oku
    string cpu, ram, storage, wifiChoice;
    getline(cin, cpu);
    getline(cin, ram);
    getline(cin, storage);
    getline(cin, wifiChoice);

    // TODO: Bir ComputerBuilder örneği oluşturun
    
    // TODO: CPU, RAM ve storage ayarlamak için method chaining kullanın
    
    // TODO: Eğer wifiChoice "yes" ise, addWifi() fonksiyonunu da çağırın
    
    // TODO: Computer nesnesini elde etmek için build() fonksiyonunu çağırın
    
    // TODO: Yapılandırmayı görüntülemek için oluşturulan bilgisayar üzerinde showSpecs() fonksiyonunu çağırın

    return 0;
}
quiz iconKendini test et

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