Harun Özer


Proje veya dijital katalog yaptırmak için
iletişim formu doldurabilirsiniz..

<< Prototype Tasarım Deseni - Prototype Design Pattern | Komut Tasarım Deseni - Command Design Pattern>>

Sorumluluk Zinciri Tasarım Deseni - Chain of Responsibility Design Pattern

Yazar harunozer 30 October 2012

Sorumluluk Zinciri Tasarım Deseni - Chain of Responsibility Design Pattern Chain of Responsibility (Sorumluluk Zinciri) tasarım deseni behavior grubununa ait, bir isteğin belli sınıflar içinde gezdirilerek ilgili sınıfın işlem yapmasını yöneten tasarım desenidir. Chain of responsibility tasarım deseninin dofactory.com a göre kullanım sıklığı 40% lardadır.

Chain of responsibility tasarım deseni; bir isteğin duruma göre farklı şekillerde işlem yapılması gereken durumlarda kullanılır. Bu tasarım deseninde isteğe cevap verebilecek sınıflar aynı arayüzü kullanır ve isteğin durumuna göre ya cevap verir ya da isteği zincirdeki sonraki nesneye gönderir. Client da zinciri oluşturur ve ilk zincire isteği gönderir. Böylece geliştirici isteğe cevap vermek için karışık karar blokları yazmaktan ve kodun karışmasından kurtulur. Chain of responsibility tasarım deseninde 3 ana yapı vardır.

Handler: İsteği işleyebilecek sınıfların uygulaması gereken interface veya abstract sınıftır. Yani zincirdeki bütün halkalar bu arayüzü uygulamak zorundadır. Bu arayüzde kendisini gösteren bir property ve isteğe cevap verebilecek bir metot tanımlı olur.

ConcreteHandler: İsteğe cevap verebilecek (veya sonraki nesneye yönlendirebilecek) gerçek sınıflardır. Bu sınıfların hepsi Handler olarak tanımlanan arayüzü uygulamak zorundadır.

Client: Zincirin oluşturan ve zincirin ilk halkasına isteği gönderen nesnedir.

Chain of responsibility tasarım deseni için örnek uml şeması aşağıdadır.

Örneğin bir video oynatıcısı uygulaması yapıyor olalım. Kullanıcı avi,mpg,flv uzantılı video dosyası seçip oynat düğmesine bastığında oluşturacağımız desene istek gönderilsin ve dosyanın uzantısına göre ilgili sınıflar tarafından oynatılsın. Uygulamamızın class diyagramı şöyledir.

Örnek uyulamamızda Handler yapısı (PlayerHandler) abstract sınıf olarak tanımlanmıştır ve içinde kendisini işaret eden bir property ve isteği işleyen veya _SonrakiHandler nesnesine gönderen abstract bir metot tanımlanmıştır. Handler yapısını yazdıktan sonra bu nesneyi uygulayan concretehandler (ConcreteHandlerMp4, ConcreteHandlerMpg, ConcreteHandlerAvi) yapılarını yani isteği işleyebilecek sınıfları yazıyoruz. Bu sınıflarda Play metodunu override edip ya isteği işliyoruz veya _SonrakiHandler nesnesine gönderiyoruz. 
 
public abstract class PlayerHandler
{
    protected PlayerHandler _SonrakiHandler;
    public PlayerHandler SonrakiHandler { set { _SonrakiHandler = value; } }
 
    public abstract void Play(string filePath);
}
 
public class ConcreteHandlerMp4 : PlayerHandler
{
    public override void Play(string filePath)
    {
        /*.mp4 uzantılı dosya ise bu sınıf cevap verir*/
        if (filePath.EndsWith(".mp4"))
            Console.WriteLine("{0} dosyası oynatılıyor(mp4 player)...", filePath);
        else
        {
            /*.mp4 uzantılı dosya değil ise _SonrakiHandler a isteği gönder*/
            if (_SonrakiHandler != null)
                _SonrakiHandler.Play(filePath);
        }
    }
}
 
public class ConcreteHandlerMpg : PlayerHandler
{
    public override void Play(string filePath)
    {
        /*.mpg uzantılı dosya ise bu sınıf cevap verir*/
        if (filePath.EndsWith(".mpg"))
            Console.WriteLine("{0} dosyası oynatılıyor(mpg player)...", filePath);
        else
        {
            /*.mpg uzantılı dosya değil ise _SonrakiHandler a isteği gönder*/
            if (_SonrakiHandler != null)
                _SonrakiHandler.Play(filePath);
        }
    }
}
 
public class ConcreteHandlerAvi : PlayerHandler
{
    public override void Play(string filePath)
    {
        /*.avi uzantılı dosya ise bu sınıf cevap verir*/
        if (filePath.EndsWith(".avi"))
            Console.WriteLine("{0} dosyası oynatılıyor(avi player)...", filePath);
        else /*isteğe cevap verebilecek son sınıf bu olduğundan .avi uzantılı değil ise hata ver*/
            Console.WriteLine("{0} Geçersiz Dosya Formatı", filePath);
 
    }
}
 
Son olarak da client yapısını oluşturuyoruz yani zinciri oluşturma ve isteği ilk zincir halkasına gönderme işlemini yapıyoruz.
static void Main(string[] args)
{
    /*zinciri oluşturacak halkaları tanımlıyoruz*/
    PlayerHandler mp4Player = new ConcreteHandlerMp4();
    PlayerHandler mpgPlayer = new ConcreteHandlerMpg();
    PlayerHandler aviPlayer = new ConcreteHandlerAvi();
 
    /*Zincirin halkalarını sıralıyoruz */
    /*İstek hangi sıra ile ConcreteHandler sınıflarına iletileceğini belirliyoruz*/
    mp4Player.SonrakiHandler = mpgPlayer;
    mpgPlayer.SonrakiHandler = aviPlayer;
 
    /*İstekleri zincirin ilk halkasına ygönderiyoruz*/
    mp4Player.Play("video.mpg");
    mp4Player.Play("video.avi");
    mp4Player.Play("video.mp4");
    mp4Player.Play("video.swf");
 
    Console.ReadKey();
 
}
 
Örnek uygulamayı aşağıdaki linkten indirebilirsiniz.
 
chain_of_responsibility_pattern_sample.rar

Tam Sayfa
Tags tasarım desenleri,
Kategoriler c#.net, Tasarım Desenleri
İşlemler
Bu Makale 3  Kez Beğenildi.
İsim :    
e-Mail :    
Web Site :  
İmage :  
Güvenlik Kodu :  

Güvenlik Resmi
Resmi Yenile
    
Yorum :  
Tasarım Desenleri ve Mimarileri