|  | 
        
            | 
                    
                        | Decorater Tasarım Kalıbı : ASP.NET ile Datagrid Örneği |  |  
                        | 
	
    
		
            | Gönderiliyor lütfen bekleyin... | 
 |  | 
        
            | Merhaba, C#nedir?com’da 
yayınladığım ilk makalemde sizlere tasarım kalıplarından Decarator 
tasarım kalıbını anlatmaya çalışacağım.Basit bir uygulama yaparak bu tasarım kalıbının 
pratikte nasıl kullanıldığını göstereceğim. 
Tasarım kalıplarına ait genel bilgiyi Singleton 
  Tasarım Deseni makalesinde bulabilirsiniz. Birkaç gün önce daha önceden 
  yaptığım bir web projesinin kodlarını gözden geçirip düzenleme(refactoring) 
  yapıyordum. Projede kullandığım DataGrid kontrollerinin çoğunda silme butonu 
  kullandığımı fark ettim. Silme butonuna tıklanıldığında javascript kodu yarıdmıyla 
  ekrana, seçilen kaydın gerçekten silinmesinin istenip istenmediğini soran bir 
  ileti çıkıyor ve seçimin sonucuna göre gerekli işlem gerçekleştiriliyordu.(şekil 
  1) 
 
  (Şekil 1)
 
 Yukarıda bahsedilen işlemi gerçekleştirebilmek için DataGrid 
  kontrolünün ItemDataBound olayında ilgili Sil butonunu bularak bu botunun Attributes 
  özelliğine aşağıdaki gibi ilgili javascript kodu ekliyordum.
 
 
 
  Evet kodumuz bu 
  haliyle gayet iyi gözüküyor ve işimizi görüyor.Fakat şunu farkettim. Sil butonu 
  kullanacağımız her datagrid için bu kodu tekrar yazmamız gerekli ve buda kod 
  tekrarını arttırıyor.Şöyle bir çözüm geliştirdim: DataGrid kontrolünden türeyen 
  yeni bir DataGrid sınıfı oluşturursam ve türettiğim DataGrid kontrolünün ItemDataBound 
  olayında yukarda bahsedilen silme işlemi yaparsam bu kodu tekrar tekrar yazmak 
  zorunda kalmayacaktım.Aşağıda DataGrid kontrolünden türeyen yeni DataGridSilButon 
  sınıfımızın kodlarını görüyoruz. 
    | private void 
      dgListe_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs 
      e) {
 if(e.Item.ItemType==ListItemType.Item 
      || e.Item.ItemType==ListItemType.AlternatingItem)
 {
 e.Item.Cells[6].Attributes.Add("onclick", 
      "return confirm(’Silmek Istediginizden Emin misiniz?’)");
 }
 }
 |  
 
 
  Yeni türettiğimiz 
  DataGrid kontrolünü sayfamıza aşağıdaki gibi register ederek kullanabiliyoruz 
    | public class 
      DataGridSil: System.Web.UI.WebControls.DataGrid {
 protected int silSutunIndex =-1;
 protected bool silOnay =true;
 
 public DataGridSil() { }
 
 public int SilSutunIndex
 {
 get{return 
      silSutunIndex ;}
 set{silSutunIndex 
      =value;}         
        }
 
 public bool SilOnay
 {
 get { return 
        silOnay; }
 set { silOnay= 
        value; }
 }
 
 protected override void OnItemDataBound(DataGridItemEventArgs e)
 {
 base.OnItemDataBound 
        (e);
 if ((silOnay==true) 
        && (silSutunIndex != -1))
 {
 e.Item.Cells[silSutunIndex ].Attributes.Add("onclick", "return 
        confirm(’Silmek Istediginizden Emin misiniz?’)");
 }
 }
 }
 
 
 
 |  
 
 
   
    | <%@ 
        Register tagprefix="dg" Namespace="MCA.Web" Assembly="MCA" 
        %> .....
 <dg:DataGridSilButon id="grid" runat="server" ..... 
        >
 <dg:DataGridSilButon>
 
 
 
 |  Artık her projede rahatça kullanabileceğimiz "sil butonu" eklenmiş 
  yeni bir datagrid nesnemiz var. Projemde eski model DataGrid’leri tek tek bu 
  yeni türettiğim DataGrid ile değiştirirken bazı DataGrid kontrolleri üzerinde 
  yönlendirme işlemi yaptığım sütunlar bulunduğunu farkettim. Mesela e-mail atma 
  sütununu çoğu DataGrid konrolünde kullanmışım.
 
 
  
 Örnek olarak E-mail sutununa tıkladığımda mail.aspx sayfasına tıkladığım sutunun 
  mail adresini parametre olarak gönderiyordum.Bunun içinde Sil butonuna benzer 
  DataGrid kontrolünün ItemDataBound olayına yönlendirme işlemini gerçekleştiren 
  javascript kodunu ekliyordum. Aklıma hemen bu yaptığım işlemler içinde daha 
  önce türettiğim DataGridSil sınıfına benzer yeni bir DataGridURL sınıfı türetmek 
  geldi.Bu yeni sınıfımda yönlendirme yapacağım sutunları belirleyecektim ve ardından 
  hangi adrese gideceklerini söyleyecektim böylece bu yönlendirme işlemi için 
  her DataGrid kontrolünün ItemDataBound olayına yazdığım koddan kurtulacaktım.
 
 Gayet iyi bir çözüm 
  olarak gözüküyordu. Projemde gözden geçirme işlemlerine devam ederken yönlendirme 
  ve silme işlemlerini bir arada yaptığım DataGrid kontrolleri olduğunu farkettim. 
  Bu kısma kadar herşey güzel gidiyordu fakat burada biraz kafam karışmıştı.Şimdi 
  ne yapmam gerekiyordu?Aklıma hemen şöyle bir fikir geldi tekrar 3. bir DataGrid 
  türetip buna DataGridMailveURL ismini verebilirdim.Bu türettiğim DataGrid’in 
  ItemDataBound olayında hem silme hemde yönlendirme işlemlerinin ikisini birden 
  yapabilirdim.Tabi ilerleyen aşamalarda yeni bir özellik kullandığım DataGrid 
  kontrolü görürsem tekrar yeni bir sınıf türetmem gerekirdi..Aşağıda ilk olarak 
  düşündüğüm çözümün UML diyagramını görüyorsunuz.
 
 
  
 Yukarıda gördüğümüz gibi DataGrid kontrolüne eklediğimiz her yeni özellik için 
  yeni bir sınıf türetmemiz gerekiyor. Ayrıca eklediğimiz iki özelliğin bir arada 
  kullanıldığı DataGrid kontrolü için de ayrıca yeni bir sınıf türetmemiz gerekiyor.Örneğin 
  resim sütunu içeren bir DataGrid kontrolüne ihtiyacımız olsun ve bu resim sütununa 
  bastığımızda ilgili resmi göstersin.Bunu yapmak için de yeni bir sınıf türetmemiz 
  gerekir.Ayrıca bu resim özelliği içeren yeni DataGrid kontrolünde silme özelliğini 
  kullanmak istiyorsak silme ve resim gösterme özelliklerini birarada içeren yeni 
  bir sınıf türetmemiz gerekir yani kısacası ekleyeceğimiz her özellik için ve 
  de bu özelliklerden bazılarını bir arada kullanacağımız DataGrid kontrolleri 
  için yeni sınıflar türetmemiz gerekir böylece kalıtım zinciri uzayıp gider.
 
 İşte takıldığım 
  bu noktada yardımıma Decorator Tasarım kalıbı yetişti.Kısaca tanımını yaparsak 
  Decorator tasarım kalıbı bize bir nesneye yeni özellikler eklemek için türetmeyi 
  kullanarak yeni sınıf oluşturmadan nesneye yeni özellikler eklememize olanak 
  sağlar. Bu işlemi türetme yenine kompozisyon kullanarak yapar.Bunu adından da 
  anlaşıldığı gibi dekorasyon işlemi gibi düşünebiliriz.Örneğin elimizde mağazadan 
  aldığımız bir mutfak dolabı var bu dolabın üstüne bizim extra ihtiyaçlarımız 
  için yeni bir raf ekletmek istiyoruz bu işlem için dolabı marangoza gönderip 
  ihtiyacımıza göre yeni bir raf eklettirebiliriz.Böyle olmasaydı dolabı üreten 
  fabrika bizim extra ihtiyacımız için yeni bir raf içeren dolap kalıbı üretecek 
  ve ardından bu kalıbı kullanarak dolap üretecek ve bu kalıptan üretilen bütün 
  dolaplar aynı olacaktı.Tabi bu extra rafı herkesin istemeyebileceğini ya da 
  herkesin değişik ihtiyaçları olduğunu düşünürsek herkesin ihtiyacı için fabrikanın 
  ayrı dolap kalıpları üretmesi gerekecekti.Ama biz ekleyeceğimiz extra özelliği 
  marangoza yaptırarak sorunun üstesinden geldik diyelim ki yarın değişik bir 
  şey ekletmek istiyorsak tekrar fabrikanın bunun için yeni bir kalıp üretmesini 
  beklemeden marangoza gönderip tekrar aynı işlemi yaptırabilirz.Örnek biraz garip 
  oldu ama umarım anladınız:)
 
 Şimdi DataGrid 
  kontrolümüze Decorator tasarım kalıbını kullanarak tekrar yeni özellikler ekleyelim 
  ve aradaki farkı görelim. Aşağıda decorator tasarım kalıbına göre tasarladığımız 
  DataGrid’in UML diyagramı gözükmektedir.
 
 
 
 
   
 Öncelikle alt sınıflarda kullanacağımız ortak özellikleri soyut DataGridDecorator 
sınıfında topluyoruz
 
 
 
  Ardından bu sınıftan 
  türeyen ve de yapıcısına parametre olarak gönderdiğimiz DataGrid kontrolüne 
  silme özelliği ekleyen yeni decorator sınıfımızı yazalım. 
    | public 
        abstract class DataGridDecorator : System.Web.UI.WebControls.DataGrid {
 protected DataGrid grid;
 public DataGridDecorator() { }
 
 public DataGridDecorator(DataGrid Grid)
 {
 this.grid =Grid;
 if(grid != null)
 {
 grid.ItemDataBound -=new DataGridItemEventHandler(Grid_ItemDataBound);
 }
 
 grid =Grid;
 
 grid.ItemDataBound +=new DataGridItemEventHandler(Grid_ItemDataBound);
 }
 
 protected abstract void Grid_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs 
        e);
 }
 
 
 
 |  
 
 
  Yukarıdaki decorator 
  sınıfıza benzer şekilde yönlendirme decorator sınıfımızıda yazarız.Burada daha 
  fazla uzatmamak için yönlendirme işlemi yapan sınıfın kodlarını yazmıyorum örnek 
  sınıfları ekteki dosyadan indirebilirsiniz. Şimdi de decorator sınıfımızın nasıl 
  kullanıldığına bakalım. Formumuzda bulunan DataGrid kontrolümüze silme ve yönlendirme 
  özelliği eklemek için neler yapacağımıza bakalım. 
    | public 
        class DataGridSil:DataGridDecorator {
 protected 
        int delcolIndex =-1;
 protected 
        bool confirmdel =true;
 
 public DataGridSil() 
        { }
 public DataGridSil(DataGrid 
        Grid):base(Grid) { }
 
 public int 
        DeleteColumnIndex
 {
 get{return 
        delcolIndex;}
 set{delcolIndex=value;}
 }
 
 public 
        bool ConfirmOnDelete
 {
 get{ 
        return confirmdel; }
 set 
        { confirmdel = value; }
 }
 
 protected 
        override void Grid_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs 
        e)
 {
 base.OnItemDataBound 
        (e);
 if (!confirmdel) 
        return;
 if 
        (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem 
        || e.Item.ItemType == ListItemType.SelectedItem)
 {
 if 
        (delcolIndex != -1)
 {
 e.Item.Cells[delcolIndex].Attributes.Add("onclick", 
        "return confirm(’Silmek Istediginizden Emin misiniz?’)");
 }
 }
 }
 }
 
 
 
 |  
 
 
  Birde decorator 
  sınıfı oluşturmadan normal türetme yoluyla nasıl yapabilirdik ona bakalım. 
    | gridByDelete 
        =new DataGridSil(dgFirmaListe); 
 gridByDelete.DeleteColumnIndex=6;
 
 gridByURL 
        =new DataGridURL(dgFirmaListe);
 
 gridByURL.setColumnURL(5,"mail.aspx?adres={5}");
 
 
 
 |  
 
 
  Gördüğümüz gibi 
  istediğimiz işlemi decorator sınıfları kullanmadan yapmak için birçok sınıf 
  türettik ve bu sınıfların hepsini ayrı ayrı kullanmak zorunda kaldık. Fakat 
  bu işlemi decorator sınıfları kullanarak yapmak için sadece yeni özellik eklemek 
  istediğimiz nesneyi özelliği içeren decorator sınıfına parametre olarak göndermemiz 
  yeterli.Ayrıca bu özellikten başka değişik bir özellik eklemek için yine aynı 
  nesneyi o özelliği içeren decorator sınıfına parametre olarak göndererek kolayca 
  yapabiliyoruz. 
    | //Sadece 
        silme özelliği içeren DataGrid için 
 DataGridSil 
        gridSil =new DataGridSil();
 
 gridSil.DeleteColumnIndex=6;
 
 //Sadece 
        yönlendirme işlemi yapan DataGrid için
 
 DataGridURL 
        gridByURL =new DataGridURL();
 
 gridByURL.setColumnURL(5,"mail.aspx?adres={5}");
 
 //Silme ve 
        yönlendirme işlemi yapan DataGrid için
 
 DataGridSilURL 
        gridSilURL =new DataGridSilURL();
 
 gridSilURL.setColumnURL(5,"mail.aspx?adres={5}");
 
 gridSilURL.DeleteColumnIndex=6;
 
 
 
 |  
 Umarım ilk makalem 
  sizlere faydalı olmuştur. Elimden geldiğince Tasarım kalıpları ile alakalı gerçek 
  uygulamalarda karşılaşılan problemleri örneklerle anlatmaya çalışacağım. Birdahaki 
  yazımda Observer Tasarım kalıbını ufak bir örnekle anlatmaya çalışacağım.Hepinize 
  iyi çalışmalar.
 
 Örnek 
  sınıfları buradan indirebilirsiniz.
 
 
 
 
                Makale:Decorater Tasarım Kalıbı : ASP.NET ile Datagrid Örneği C#, Visual C# ve .NET Cihat Altuntaş
 | 
        
            |  | 
        
            |  | 
        
            | 
                    
                        
                            
                        
                            Eklenen Son 10 
                            Bu Konuda Geçmiş 10 
                        
                            Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
                         
                            Son Eklenen 10 Makale Yükleniyor
                         
                            Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
                         | 
        
            |  |