Menu
Coddy logo textTech

Şablon Metot Kalıbı

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

Template Method deseni, bir algoritmanın iskeletini bir temel sınıfta tanımlar ve alt sınıfların, algoritmanın genel yapısını değiştirmeden belirli adımları geçersiz kılmasına (override) olanak tanır. Tüm algoritmaları yer değiştiren Strategy'nin aksine, Template Method algoritmayı sabit tutarken bireysel adımların özelleştirilmesine izin verir.

Temel sınıf, şablon yöntemini (algoritmayı) uygular ve alt sınıfların sağlaması gereken soyut veya sanal yöntemleri çağırır:

#include <iostream>

class DataProcessor {
public:
    // Şablon metodu - algoritma iskeletini tanımlar
    void process() {
        loadData();
        processData();
        saveResults();
    }
    
    virtual ~DataProcessor() = default;
    
protected:
    virtual void loadData() = 0;      // Uygulanması zorunludur
    virtual void processData() = 0;   // Uygulanması zorunludur
    
    // Hook (Kanca) - varsayılan davranışla isteğe bağlı geçersiz kılma
    virtual void saveResults() {
        std::cout << "Saving to default location\n";
    }
};

class CSVProcessor : public DataProcessor {
protected:
    void loadData() override {
        std::cout << "Loading CSV file\n";
    }
    void processData() override {
        std::cout << "Parsing CSV data\n";
    }
};

class JSONProcessor : public DataProcessor {
protected:
    void loadData() override {
        std::cout << "Loading JSON file\n";
    }
    void processData() override {
        std::cout << "Parsing JSON data\n";
    }
    void saveResults() override {
        std::cout << "Saving to cloud storage\n";
    }
};

int main() {
    CSVProcessor csv;
    csv.process();  // Varsayılan saveResults'ı kullanır
    
    JSONProcessor json;
    json.process(); // Özel saveResults'ı kullanır
}

process() yöntemi şablon yöntemdir (template method); adımların sabit sırasını tanımlar. Alt sınıflar loadData() ve processData() yöntemlerini farklı şekilde uygular, ancak sıra asla değişmez. saveResults() yöntemi bir "hook"tur (kanca); alt sınıfların isteğe bağlı olarak geçersiz kılabileceği varsayılan bir uygulamaya sahiptir.

Değişmez adımlara sahip bir algoritmanız olduğunda ancak belirli işlemlerde esnekliğe ihtiyaç duyduğunuzda veya benzer sınıflar arasında kod tekrarından kaçınmak istediğinizde Template Method'u kullanın.

challenge icon

Görev

Kolay

Template Method desenini kullanarak bir Rapor Oluşturucu (Report Generator) sistemi inşa edelim. Farklı rapor türlerinin (satış raporları ve envanter raporları gibi) aynı oluşturma sürecini takip ettiği, ancak her rapor türünün belirli adımları özelleştirdiği bir iskelet oluşturacaksınız. Bu, Template Method için mükemmel bir senaryodur; genel iş akışı sabit kalırken bireysel adımlar değişir.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • ReportGenerator.h: Şablon metodunu içeren soyut temel sınıfı tanımlayın.

    Rapor oluşturma algoritmasının iskeletini tanımlayan bir ReportGenerator sınıfı oluşturun. Şablon metodunuz olan generateReport(), şu adımları sırasıyla yürütmelidir:

    1. gatherData() — saf sanal (pure virtual), alt sınıflar tarafından uygulanmalıdır
    2. formatReport() — saf sanal, alt sınıflar tarafından uygulanmalıdır
    3. addHeader() — varsayılan davranışı --- Report --- yazdıran bir kanca (hook)
    4. printReport() — saf sanal, alt sınıflar tarafından uygulanmalıdır

    addHeader() metodu, alt sınıfların başlığı özelleştirmek için isteğe bağlı olarak geçersiz kılabileceği (override) bir kanca görevi görür.

  • Reports.h: İki somut rapor oluşturucuyu uygulayın.

    Şu özelliklere sahip bir SalesReport sınıfı oluşturun:

    • gatherData() şunu yazdırır: Gathering sales data from database
    • formatReport() şunu yazdırır: Formatting sales figures
    • printReport() şunu yazdırır: Sales Total: $[amount] (burada amount yapıcıya (constructor) iletilen değerdir)

    Şu özelliklere sahip bir InventoryReport sınıfı oluşturun:

    • gatherData() şunu yazdırır: Scanning inventory records
    • formatReport() şunu yazdırır: Organizing inventory by category
    • addHeader() kancayı geçersiz kılarak şunu yazdırır: === Inventory Report ===
    • printReport() şunu yazdırır: Items in stock: [count] (burada count yapıcıya iletilen değerdir)

    Her iki sınıf da ilgili değerlerini (amount veya count) yapıcıları aracılığıyla kabul etmelidir.

  • main.cpp: Template Method desenini gösterin.

    İki girdi okuyun:

    1. Satış tutarı (tam sayı)
    2. Envanter sayısı (tam sayı)

    Satış tutarı ile bir SalesReport oluşturun ve raporu üretin. Ardından envanter sayısı ile bir InventoryReport oluşturun ve raporu üretin. Okunabilirlik için iki rapor arasına boş bir satır yazdırın.

Örneğin, 15000 ve 250 girdileriyle:

Gathering sales data from database
Formatting sales figures
--- Report ---
Sales Total: $15000

Scanning inventory records
Organizing inventory by category
=== Inventory Report ===
Items in stock: 250

8500 ve 120 girdileriyle:

Gathering sales data from database
Formatting sales figures
--- Report ---
Sales Total: $8500

Scanning inventory records
Organizing inventory by category
=== Inventory Report ===
Items in stock: 120

Her iki raporun da generateReport() içinde tanımlanan tam olarak aynı adımlar dizisini nasıl takip ettiğine, ancak her birinin bu adımları nasıl farklı şekilde uyguladığına dikkat edin. InventoryReport ayrıca başlığı özelleştirmek için kanca metodunu geçersiz kılmayı gösterirken, SalesReport varsayılanı kullanır. Bu, Template Method deseninin iş başındaki halidir; algoritma yapısı temel sınıfta kilitlenmiştir, ancak ayrıntılar esnektir.

Kopya kağıdı

Template Method deseni, bir algoritmanın iskeletini bir temel sınıfta tanımlar ve alt sınıfların, algoritmanın genel yapısını değiştirmeden belirli adımları geçersiz kılmasına (override) olanak tanır.

Temel sınıf, şablon yöntemi (algoritmayı) uygular ve alt sınıfların sağlaması gereken soyut veya sanal yöntemleri çağırır:

#include <iostream>

class DataProcessor {
public:
    // Şablon yöntemi - algoritma iskeletini tanımlar
    void process() {
        loadData();
        processData();
        saveResults();
    }
    
    virtual ~DataProcessor() = default;
    
protected:
    virtual void loadData() = 0;      // Uygulanması zorunludur
    virtual void processData() = 0;   // Uygulanması zorunludur
    
    // Hook - varsayılan davranışla isteğe bağlı geçersiz kılma
    virtual void saveResults() {
        std::cout << "Saving to default location\n";
    }
};

class CSVProcessor : public DataProcessor {
protected:
    void loadData() override {
        std::cout << "Loading CSV file\n";
    }
    void processData() override {
        std::cout << "Parsing CSV data\n";
    }
};

class JSONProcessor : public DataProcessor {
protected:
    void loadData() override {
        std::cout << "Loading JSON file\n";
    }
    void processData() override {
        std::cout << "Parsing JSON data\n";
    }
    void saveResults() override {
        std::cout << "Saving to cloud storage\n";
    }
};

Şablon yöntemi, sabit bir adım dizisini tanımlar. Alt sınıflar soyut yöntemleri farklı şekilde uygular, ancak sıra asla değişmez. Hook yöntemleri, alt sınıfların isteğe bağlı olarak geçersiz kılabileceği varsayılan uygulamalara sahiptir.

Değişmez adımları olan bir algoritmanız olduğunda ancak belirli işlemlerde esnekliğe ihtiyaç duyduğunuzda veya benzer sınıflar arasında kod tekrarını önlemek istediğinizde Template Method kullanın.

Kendin dene

#include <iostream>
#include "Reports.h"

using namespace std;

int main() {
    // Girdileri oku
    int salesAmount;
    int inventoryCount;
    cin >> salesAmount;
    cin >> inventoryCount;
    
    // TODO: salesAmount ile bir SalesReport oluşturun ve bunu oluşturun (generate)
    
    // TODO: Raporlar arasına boş bir satır yazdırın
    
    // TODO: inventoryCount ile bir InventoryReport oluşturun ve bunu oluşturun (generate)
    
    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