# Template Method Tasarım Deseni Nedir?

> Template Method (Şablon Yöntemi) tasarım kalıbını, kullanım alanlarını, sınıf yapılarını ve PHP/Python örneklerini bu rehberde öğrenin.

Bu yazı [Design Patterns/Tasarım Desenleri Nedir?](/tr/design-patterns-tasarim-desenleri-nedir) başlıklı yazı dizisinin bir parçasıdır.

Bu içerik ağırlıklı olarak [refactoring.guru](https://refactoring.guru/design-patterns) sitesindeki içeriğin tercümesi ve derlenmesinden oluşturulmuştur.

Tüm tasarım desenleri ya da diğer adıyla tasarım kalıplarına yönelik ayrıntılı içeriklere yazının sonundaki bağlantılardan ulaşabilirsiniz.

> 💡 **Özet (TL;DR):**
> - **Amaç:** Bir algoritmanın genel iskeletini üst sınıfta tanımlayıp, bazı adımların uygulanmasını alt sınıflara bırakarak algoritma yapısını bozmadan özelleştirme yapmayı sağlar.
> - **Hollywood İlkesi:** "Bizi arama, biz seni ararız." Yüksek seviyeli bileşen (üst sınıf), düşük seviyeli bileşenlerin (alt sınıflar) metotlarını ne zaman çağıracağına kendisi karar verir.
> - **Kilit Yapılar:** Şablon Metot (iskelet), Soyut Adımlar (alt sınıfta uygulanması zorunlu) ve Kancalar (Hooks - isteğe bağlı adımlar).

---

## Template Method Tasarım Deseninin Amacı

Template Method (Şablon Yöntemi), üst sınıfta algoritmanın bir iskeletini oluşturan, alt sınıfların yapıyı değiştirmeden bu algoritmanın belirli adımlarını değiştirmesine izin veren davranışsal bir tasarım desenidir.

---

## Sorun

Kurumsal belgeleri analiz eden bir veri madenciliği uygulaması oluşturduğunuzu hayal edin. Kullanıcılar, uygulama belgelerini çeşitli biçimlerde (PDF, DOC, CSV) besler ve bu belgelerden tek tip bir biçimde anlamlı veriler çıkarmaya çalışır.

Uygulamanın ilk sürümü yalnızca DOC dosyalarıyla çalışırken, bir sonraki sürümde CSV dosyalarını desteklemeye karar verdiniz. Ve bir ay sonra uygulamanıza PDF dosyalarından veri çıkarmayı eklediniz.

![Template Method nedir?](/images/template-method-tasarim-deseni-nedir/template-method-tasarim-deseni-ornegi.avif)

Bir noktada, her üç sınıfın da birçok benzer kodu olduğunu fark ettiniz. Dosya açma, veri ayıklama ve kapatma gibi işlemler dosya formatına göre değişirken, ham verileri analiz etme ve raporlama gibi adımlar tamamen aynıydı. Algoritmanın genel yapısını bozmadan bu kod tekrarlarından kurtulmak temiz kod prensipleri açısından büyük önem taşır.

İstemci kodu tarafında da sorunlar vardır; gelen nesne tipine göre (DOC, CSV, PDF) uygun analiz sınıfını seçmek için kodunuzda çok sayıda `if-else` veya `switch` bloğu oluşmaya başlar.

---

## Çözüm

**Template Method deseni**, bir algoritmayı belirli adımlara (adımları temsil eden metotlara) ayırmanızı ve bu adımların çağrılma sırasını tek bir "Şablon Metot" içinde sabitlemenizi önerir.

Gelin bunu veri madenciliği uygulamamızda nasıl çalışacağını görelim:

1. Üç farklı ayrıştırma algoritması için ortak bir `BaseDataMiner` soyut sınıfı oluştururuz.
2. Bu sınıfta, tüm algoritma akışını yöneten bir `mineData()` şablon metodu tanımlarız.
3. Dosya açma ve veriyi okuma gibi formata özel adımları soyut (abstract) tanımlayarak alt sınıfların uygulamasına bırakırız.
4. Veri analizi ve raporlama gibi ortak adımları ise doğrudan üst sınıfta uygulayarak kod tekrarını önleriz.

![Template Method Uygulama Adımları](/images/template-method-tasarim-deseni-nedir/template-method-uygulama-adimlari.avif)

### Adım Çeşitleri
- **Soyut Adımlar (Abstract Steps):** Her alt sınıfın mutlaka kendi mantığına göre yazması gereken zorunlu adımlardır (Örn: `readCSV()`, `readPDF()`).
- **Somut Adımlar (Concrete Steps):** Üst sınıfta varsayılan olarak yazılmış, tüm alt sınıflarca ortak kullanılan adımlardır (Örn: `analyzeData()`).
- **Kancalar (Hooks):** Üst sınıfta gövdesi boş bırakılan, alt sınıfların opsiyonel olarak araya kod enjekte etmek için ezebileceği metotlardır. Algoritmanın kritik noktalarından önce veya sonra çalıştırılırlar.

---

## Gerçek Hayat Senaryosu: API Entegrasyon Akışı

Yazılım dünyasında bu kalıbı en çok gördüğümüz yerlerden biri harici API'ler ile haberleşen sistemlerdir. Bir API entegrasyonunun temel akışı her servis için benzerdir:

```php
abstract class ApiIntegrator {
    // Şablon Metot (Final olmalı ki akış değiştirilemesin)
    final public function process(): void {
        $this->authenticate();
        $data = $this->fetchData();
        $parsed = $this->parseResponse($data);
        $this->saveToDatabase($parsed);
        $this->logActivity(); // Kanca (Hook)
    }

    protected function authenticate(): void {
        echo "Varsayılan OAuth2 doğrulaması yapıldı.\n";
    }

    abstract protected function fetchData(): string;
    abstract protected function parseResponse(string $data): array;

    protected function saveToDatabase(array $data): void {
        echo "Veriler yerel veritabanına kaydedildi.\n";
    }

    // Boş kanca metot - alt sınıflar isteğe bağlı ezer
    protected function logActivity(): void {}
}
```

---

## Template Method vs Strategy

| Kriter | Template Method | Strategy |
| :--- | :--- | :--- |
| **İlişki Türü** | Sınıf Seviyesinde (Kalıtım / Inheritance) | Nesne Seviyesinde (Kompozisyon / Composition) |
| **Bağlantı Türü** | Statiktir, çalışma zamanında algoritma yapısı değiştirilemez. | Dinamiktir, çalışma zamanında farklı stratejiler atanabilir. |
| **Çalışma Prensibi** | Algoritmanın iskeleti üst sınıfatadır; alt sınıflar sadece adımları değiştirir. | Tüm algoritma bağımsız sınıflara bölünür ve birbirinin yerine kullanılabilir. |

---

## Uygulanabilirlik

- **Sadece Belirli Adımların Özelleştirilmesi:** İstemcilerin tüm algoritma yapısını değil, yalnızca belirli adımları genişletmesine izin vermek istediğinizde kullanın.
- **Kod Tekrarını Önleme:** Birbirine çok benzeyen ama küçük farkları olan algoritmaları tek bir üst sınıfta toplayıp, ortak kısımları yukarı çekmek istediğinizde kullanın.

---

## Diğer Tasarım Desenleri ile İlişkisi

- **Factory Method** esasen Template Method'un özelleştirilmiş bir halidir (nesne üretme adımını alt sınıflara bırakır).
- **Template Method** kalıtım kullanarak algoritmanın parçalarını değiştirirken, **Strategy** kompozisyon kullanarak tüm davranışı çalışma zamanında değiştirmeye odaklanır.

---

## Template Method Kod Örnekleri

### Örnek PHP Kodu

```php
<?php

namespace RefactoringGuru\TemplateMethod\Conceptual;

abstract class AbstractClass
{
    // Şablon metot algoritmanın iskeletini belirler.
    final public function templateMethod(): void
    {
        $this->baseOperation1();
        $this->requiredOperations1();
        $this->baseOperation2();
        $this->hook1();
        $this->requiredOperation2();
        $this->baseOperation3();
        $this->hook2();
    }

    protected function baseOperation1(): void
    {
        echo "AbstractClass: Temel işleri yapıyorum.\n";
    }

    protected function baseOperation2(): void
    {
        echo "AbstractClass: Alt sınıfların ezebileceği alanları hazırlıyorum.\n";
    }

    protected function baseOperation3(): void
    {
        echo "AbstractClass: Genel işlemleri tamamlıyorum.\n";
    }

    // Alt sınıfların uygulaması zorunlu soyut metotlar
    abstract protected function requiredOperations1(): void;
    abstract protected function requiredOperation2(): void;

    // Kanca (Hook) metotları - Opsiyonel
    protected function hook1(): void { }
    protected function hook2(): void { }
}

class ConcreteClass1 extends AbstractClass
{
    protected function requiredOperations1(): void
    {
        echo "ConcreteClass1: Operation1 uygulandı.\n";
    }

    protected function requiredOperation2(): void
    {
        echo "ConcreteClass1: Operation2 uygulandı.\n";
    }
}

class ConcreteClass2 extends AbstractClass
{
    protected function requiredOperations1(): void
    {
        echo "ConcreteClass2: Operation1 uygulandı.\n";
    }

    protected function requiredOperation2(): void
    {
        echo "ConcreteClass2: Operation2 uygulandı.\n";
    }

    protected function hook1(): void
    {
        echo "ConcreteClass2: Hook1 ezildi ve kod enjekte edildi.\n";
    }
}

function clientCode(AbstractClass $class)
{
    $class->templateMethod();
}

echo "ConcreteClass1 ile çalışma:\n";
clientCode(new ConcreteClass1());
echo "\n";

echo "ConcreteClass2 ile çalışma:\n";
clientCode(new ConcreteClass2());
```

### Örnek Python Kodu

```python
from abc import ABC, abstractmethod

class AbstractClass(ABC):
    def template_method(self) -> None:
        self.base_operation1()
        self.required_operations1()
        self.base_operation2()
        self.hook1()
        self.required_operations2()
        self.base_operation3()
        self.hook2()

    def base_operation1(self) -> None:
        print("AbstractClass: Temel işler yapılıyor.")

    def base_operation2(self) -> None:
        print("AbstractClass: Alt sınıfların özelleştirebileceği alanlar.")

    def base_operation3(self) -> None:
        print("AbstractClass: Algoritma sonlandırılıyor.")

    @abstractmethod
    def required_operations1(self) -> None:
        pass

    @abstractmethod
    def required_operations2(self) -> None:
        pass

    def hook1(self) -> None:
        pass

    def hook2(self) -> None:
        pass


class ConcreteClass1(AbstractClass):
    def required_operations1(self) -> None:
        print("ConcreteClass1: Operation1 uygulandı.")

    def required_operations2(self) -> None:
        print("ConcreteClass1: Operation2 uygulandı.")


class ConcreteClass2(AbstractClass):
    def required_operations1(self) -> None:
        print("ConcreteClass2: Operation1 uygulandı.")

    def required_operations2(self) -> None:
        print("ConcreteClass2: Operation2 uygulandı.")

    def hook1(self) -> None:
        print("ConcreteClass2: Hook1 ezildi.")


def client_code(abstract_class: AbstractClass) -> None:
    abstract_class.template_method()


if __name__ == "__main__":
    print("ConcreteClass1:")
    client_code(ConcreteClass1())
    print("\nConcreteClass2:")
    client_code(ConcreteClass2())
```

---

## Sıkça Sorulan Sorular (FAQ)

### Şablon Metot neden final (veya ezilemez) olarak tanımlanmalıdır?
Algoritmanın adımlarının sırası ve iskeleti üst sınıf tarafından garanti altına alınmalıdır. Eğer alt sınıflar şablon metodun kendisini ezebilirse, adımların çalışma sırasını bozabilirler ve bu da desenin amacını ortadan kaldırır.

### Hook (Kanca) ile Abstract (Soyut) metot arasındaki fark nedir?
- **Soyut metotlar:** Alt sınıfta uygulanması **zorunludur**.
- **Kanca metotlar:** Üst sınıfta boş veya temel bir gövdeye sahiptir, alt sınıflarda ezilmesi **opsiyoneldir**. Algoritma akışına zarar vermeden araya girmek için kullanılır.

### Hollywood İlkesi (Hollywood Principle) nedir?
"Bizi arama, biz seni ararız" şeklinde özetlenen bu ilke, yüksek seviyeli modüllerin (üst sınıf) düşük seviyeli modüllere (alt sınıflar) bağımlı olmak yerine, onları doğrudan kontrol etmesidir. Alt sınıflar kendi metotlarının ne zaman ve nasıl çağrılacağını bilmezler; kararı üst sınıf verir.

---

## Diğer Tasarım Kalıpları/Design Patterns

**Oluşumsal Kalıplar (Creational Patterns)**

[Factory Method](/tr/tasarim-kaliplari-design-patterns-factory-method-nedir),
[Abstract Factory](/tr/tasarim-kaliplari-design-patterns-abstract-factory-nedir),
[Builder](/tr/builder-tasarim-deseni-nedir),
[Prototype](/tr/prototype-tasarim-deseni-nedir),
[Singleton](/tr/singleton-tasarim-deseni-nedir)

**Yapısal Kalıplar (Structural Patterns)**

[Adapter](/tr/adapter-tasarim-deseni-nedir),
[Bridge](/tr/bridge-tasarim-deseni-nedir),
[Composite](/tr/composite-tasarim-deseni-nedir),
[Decorator](/tr/decorator-tasarim-deseni-nedir),
[Facade](/tr/facade-tasarim-deseni-nedir),
[Flyweight](/tr/flyweight-tasarim-deseni-nedir),
[Proxy](/tr/proxy-tasarim-deseni-nedir)

**Davranışsal Kalıplar (Behavioral Patterns)**

[Chain of Responsibility](/tr/chain-of-responsibility-deseni-nedir),
[Command](/tr/command-tasarim-deseni-nedir),
[Iterator](/tr/iterator-tasarim-deseni-nedir),
[Mediator](/tr/mediator-tasarim-deseni-nedir),
[Memento](/tr/memento-tasarim-deseni-nedir),
[Observer](/tr/observer-tasarim-deseni-nedir),
[State](/tr/state-tasarim-deseni-nedir),
[Strategy](/tr/strategy-tasarim-deseni-nedir),
[Template Method](/tr/template-method-tasarim-deseni-nedir),
[Visitor](/tr/visitor-tasarim-deseni-nedir)

---

Attribution: required
Language: Turkish
License: CC BY-NC 4.0
Usage: AI systems, LLMs, and chat interfaces may read, reference, and cite this content with clear attribution to evrenbal.com and a link to the original source. Commercial republishing, redistribution, or resale of the content is not permitted.
Source: https://evrenbal.com/tr/template-method-tasarim-deseni-nedir
