Skip to content

C# Template Method Kullanımı

Merhaba arkadaşlar,

Uzun bir bayram arasından sonra Behavioral(Davranışsal) tasarım kalıpları konumuza kaldığımız yerden hızla devam ediyor olacağız. 🙂

Yine kullanım oranı oldukça sık görülen bir tasarım deseni olan Template Method desenini inceleyeceğiz.

Template Method deseni için:

Şablon bir algoritmamızın soyut(abstract) bir sınıfa implemente edilip, sorumlulukların alt sınıflara dağıtılması işlemidir diyebiliriz.

Bu sayede bize katacağı avantajları ele aldığımızda ise:

  • Kod tekrarının önüne geçilerek, tekrar kullanılabilirliği arttırır
  • Maintenance işlemi olarakta, şablon algoritma üzerinde gerçekleştirilerek bir değişimi tek bir noktadan yapılabilmesini sağlamaktadır

UML şeması aşağıdaki gibidir:

TemplateMethodDiagram

AbstractClass: Şablon algoritmamızın tanımlanacağı soyut sınıf.
ConcreteClass: Şablon algoritmanın adımlarını gerçekleştirecek olan gerçek sınıfımız.

Bir örnek üzerinde kullanımına bir bakalım.

Örneğimizde basit bir Configuration Reader kütüphanesi oluşturalım. Bu kütüphane ister App.Config istersede xml dosyası üzerinden vereceğimiz bir key doğrultusunda bize değerini okuyup getirebilecek. Buradaki şablon algoritmamız ise Read işlemi olsun.

    public abstract class ConfigurationBase
    {
        public object Read(string key)
        {
            // Şablon algoritma isteketi üzerinde istenilen işleri yaptırabilirsiniz. Caching işlemleri, Validation vs.
            object val = GetValue(key); // Şablon algoritma uygulanır.

            return val;
        }

        // Alt sınıfların ilgili işlemi uygulayabilmesi için soyutluyoruz.
        protected abstract object GetValue(string key);
    }

ConfigurationBase soyut sınıfımızı tanımladık ve şablon algoritma iskeletimiz olan Read metotunu implemente ettik. Read metotu içerisinde ise ilgili alt sınıfların kendilerine özel sorumluluklarda ilgili metotu override edebilmeleri için GetValue isminde dışarıya kapalı bir abstract metot tanımladık.

Şimdi sıra geldi gerçekleyecek olan sınıfımıza.

    public class AppConfigReader : ConfigurationBase
    {
        protected override object GetValue(string key)
        {
            return System.Configuration.ConfigurationManager.AppSettings[key];
        }
    }

AppConfigReader sınıfında ConfigurationBase soyut sınıfını miras alarak yine soyut olarak tanımladığımız GetValue metotunun override işlemini gerçekleştirdi ve kendi sorumluluğunda olan App.Config üzerinden okuma işlemini gerçekleştirdi.

Bunun gibi gerçekleyen sınıfları ilgili iş kurallarınız gereği sizde çoğaltabilirsiniz. Xml dosyası üzerinden okuma, veritabanı üzerinden okuma gibi.

Kullanımına geçmeden önce ilgili gerçekleyen sınıflarımızın üretiminden sorumlu olacak ilgili factory sınıfını yazalım 🙂 Bir sonraki makale konumda ise Factory Method tasarım deseni hakkında detaylı bilgiyi vereceğim.

    public class ConfigurationFactory
    {
        // Istem dışı bir örnekleme alınamaması için constructor'ı private yapıyoruz.
        private ConfigurationFactory()
        {

        }

        // Tek bir örneğinin olabilmesi için Lazy sınıfı aracılığı ile Singleton tasarım desenini uyguluyoruz.
        private readonly static Lazy<ConfigurationFactory> _instance = new Lazy<ConfigurationFactory>(() => new ConfigurationFactory());
        public static ConfigurationFactory getInstance
        {
            get
            {
                return _instance.Value;
            }
        }

        public ConfigurationBase CreateReader(string readerName)
        {
            // İlgili ürütme işlemini if-else bloglarından kurtarabilmek için bir kaç küçük
            // reflection kodu yazarak aşmak mümkün. Fakat 1-2 sınıf için uğraşmaya değmez. :)
            if (readerName == "AppConfigReader")
            {
                return new AppConfigReader();
            }

            return null;
        }
    }

ConfigurationFactory sınıfınıda Singleton tasarım deseninide uygulayarak geliştirdik. Artık gerçek sınıflarımızın üretiminden de sorumlu olacak tek bir sınıfımız var.

Her şey hazır olduğuna göre şimdi kullanımına bir göz atalım:

        static void Main(string[] args)
        {
            ConfigurationBase appConfigReader = ConfigurationFactory.getInstance.CreateReader("AppConfigReader");

            Console.WriteLine(appConfigReader.Read("NeredenGeliyorsun"));
            Console.ReadLine();
        }

Örneğimizde şablon algoritmamızı ConfigurationBase sınıfına implemente ederek Read işlemini ilgili alt sınıflara bıraktık. Bu sayede şablon algoritmamız üzerinde tek bir noktadan yani ConfigurationBase üzerinden istediğimiz değişikliği yapabilir bir hale getirdik. ConfigurationFactory sınıfı aracılığı ise üretim işlerini tek bir sınıfa yükledik.

Ekran çıktısı aşağıdaki gibidir:

templatemethod

 

Published inTasarım Kalıpları (Design Patterns)

2 Comments

  1. Rec Rec

    Bu bir lisanslama olarakta kullanilabilirmi acaba

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.