Template Design Pattern

Template Design Pattern

Template design pattern adından da anlaşılabileceği üzere size bir şablon sunar. Bir akış ya da bir yapı düşünün. Arka arkaya ilerleyecek bir process. Bu processte belli aşamalar yahut basamaklar hep aynı iken belli kısımlar da değişken olsun. İşte bu aynı olan kısımlar sizin değişken basamağınız için bir template yani şablon oluşturuyor.

Peki buradaki amaç ne ? Bana göre en önemli soru bu.. Amaç bir iş için iskelet yani şablon bir algoritma ya da akış belirleyip bu processi uygulayacak tüm classlara bunu akışı uygulatmak. Implementasyon tarafında yapacağımız ise, ana concrete sınıflarımızın türeyeceği bir adet soyut abstract class yaratmak ve bu abstract classta, tüm concrete classlar için aynı olan fonksiyonellikleri direkt olarak implemente etmek ancak tüm classların kendisine özgü implemente edeceği processleri de classın kendi içerisine bırakarak, parentte abstract metot olarak tanımlamak. Tabi bu saydığım ortak concrete metotlar ve classın kendi implemente edeceği metotlar arka arkaya bir process oluşturmalı ki bu da bir template metot üzerinden dışarıya açılabilsin.

Bu da bizlere

  • Kod tekrarlarından kurtulmak.
  • Maintenance’i yüksek bir kod elde etmek.
  • Akış süreci düzgün ve kolaylıkla değiştirilebilir bir süreç

Bir örnek ile devam edelim. Örneğimizde bir alışveriş sepetimiz olsun ve bu alışveriş sepetine attığımız ürünlerin ödeme süreci olsun. Bu ödeme süreci genel akış olarak tüm ürünler için aynı olmakla birlikte ürün bazında bazı stepleri farklılık gösterebilir olacaktır ki bu da tam olarak template design pattern kullanmamız gereken senaryodur. Televizyon ve buzdolabi olan iki ürünümüzün satın alma süreci ; başlangıç, ürün seçimi, ödeme ve bitiş olmak üzere her ürün için genel geçer 4 stepten oluşsun ve başlangıç ve bitiş tüm ürünler için ortak iken ürün seçimi ve ödeme şekli stepleri üründen ürüne farklılık göstersin. Haydi kodlayalım

enum OdemeTipi
{
   Pesin,
   Taksit
}
  • Aşağıda alışveriş isimli classımız soyut ana classımız olup template’i içerisinde barındırır. Görüldüğü üzere her alt class için ortak olacak Baslat ve Bitir metotları burada direkt olarak implemente edilmişken implementasyonu classtan classa değişecek Urun ve OdemeSekli metotları ise implementasyonu classlara bırakılmak üzere abstract tanımlanmıştır. En sonda da TemplateMethod adında bir metotla bu concrete ve abstract metotların oluşturduğu process sıralı bir şekilde tüm classların kullanması için sunulmuştur.
abstract class Alisveris
{
   protected string UrunAdi;
   protected OdemeTipi odemeTipi;
   void Baslat() 
   {
      Console.WriteLine("Alışveriş başladı."); 
   }
   void Bitir() 
   {
      Console.WriteLine($"Alışveriş bitti.{UrunAdi} {odemeTipi} yöntemiyle alınmıştır.");
   }
   abstract public void Urun();
   abstract public void OdemeSekli();
   public void TemplateMethod()
   {
     Baslat();
     Urun();
     OdemeSekli();
     Bitir();
   }
}
  • Televizyon classı abstract alışveriş classından türetilip kendine özgü olan işlemleri OdemeSekli ve Urun kendi içerisinde implemente edilmiştir.
class Televizyon : Alisveris
{
   public override void OdemeSekli()
   {
     odemeTipi = OdemeTipi.Pesin;
   }

   public override void Urun()
   {
     UrunAdi = "Televizyon";
   }
}
  • Buzdolabıclassı abstract alışveriş classından türetilip kendine özgü olan işlemleri OdemeSekli ve Urun kendi içerisinde implemente edilmiştir.
class Buzdolabi : Alisveris
{
   public override void OdemeSekli()
   {
     odemeTipi = OdemeTipi.Taksit;
   }

   public override void Urun()
   {
     UrunAdi = "Buzdolabı";
   }
} 
  • Main classta da Televizyon ve Buzdolabi classları örneklenip bize bir şablon sunan Template metot call edilmiştir. Bu template metotların çıktısı olarak, her  class için ortak olan metotlar ortak sonuç getirecekken classın kendisine özgü olan metotlar ise kendi implemente ettikleri sonucu getirecektir ve yukarıda da bahsettiğimiz gibi ana template akış processi aynı olacaktır.
static void Main(string[] args)
{
   Alisveris a1 = new Televizyon();
   a1.TemplateMethod();

   Console.WriteLine("***********");

   Alisveris a2 = new Buzdolabi();
   a2.TemplateMethod();

   Console.Read();
}

(Örnek kod https://www.gencayyildiz.com/blog/c-template-method-design-patterntemplate-method-tasarim-deseni/’den alıntıdır..)