15 Mayıs 2015 Cuma

Kalıtımsal Eşleme


Herkese merhabalar.

    Bugün sizlere kalıtımsal eşleme ve nasıl gerçekleştireceğimizden bahsedeceğim. Kalıtım denilince benim aklıma gelen ilk şey ata bir sınıf ve bu ata sınıftan türeyen bir alt sınıftır. Gelin kalıtım konusunu bir detaylandıralım. C# nesne tabanlı bir programlama dilidir, ve bu özellik C#'ın en önemli özelliklerinden biridir. C# yüzde yüz nesne tabanlı dil olması nedeniyle programcılara birçok yönden kolaylıklar sağlamaktadır. Peki bu kalıtım nedir ne işe yarar program geliştiricilere ne gibi kolaylıklar sağlar [1].

    Kalıtım, nesne yönelimli programlamanın en önemli özelliklerinden biridir. Miras alma yolu ile sınıflar birbirinden türetilebilir. Yani mevcut sınıflardan yeni bir sınıf üretme şekli olarak tanımlanabilmektedir. Bu işlemde, türeyen sınıflar türemiş sınıf, kendisinden yeni sınıfların oluşturulduğu sınıflara ise temel sınıf adı verilir [2].

    Türeyen sınıflar, türedikleri sınıfların özelliklerini devralırlar, bununla birlikte kendilerine de özel olarak özellikleri mevcuttur. .NET ortamında bir sınıf sadece bir sınıftan türeyebilir; fakat bir temel sınıf bir çok sınıf türetebilir. Miras almanın temel amacı sınıflar arasında ilişki kurmaktır [2]. Gelin hep birlikte kalıtımın Fluent NHibernate'deki kullanımına bir bakalım.

Kalıtımın Fluent NHibernate'deki kullanımı aşağıdaki üç şekilde gerçekleşmektedir.

  • Table Per Hierarchy (TPH);
  • Table Per Type (TPT);
  • Table Per Concrete Class (TPC).


Table Per Hierarchy (TPH):


    TPH kalıtım yönteminde kalıtım, veritabanının discriminator kısmı gibi herhangi bir koşul ile tanımlanan  koşullu eşleştirmeye bağımlıdır. Ayrıca, kalıtım ağacı sadece bir tablodan üretilmiştir [3].

Table Per Type (TPT):


    TPT, veritabanının ayrı tablolarında açıklanan kalıtımdır. Her tablo ilave olarak detay bulundurur. Bu detaylar, tablonun atasına bağlı olan yeni tipleri açıklamaktadır [3].

Table Per Concrete Class (TPC)


    Bu tip kalıtımda, her sınıf kendi tablosunu içerdiği bir kalıtım hiyerarşisi içerisindedir. Genel özellikler, ayrı bir tabloya konmaktansa her bir tablo içerisine tekrar tekrar yazılır [3].

Kalıtım tiplerini inceledikten sonra gelin hep birlikte bir örnek üzerinden kalıtımı daha iyi anlayalım.

 public class Iletisim  
 {  
   public virtual Guid Id { get; set; }  
   public virtual string Baslik{ get; set; }  
   public virtual string İcerik { get; set; }  
 }  
 public class SMS : Iletisim  
 {  
 }  
 public class Mail : Iletisim  
 {  
 }  


 public class IletisimMap : ClassMap<Iletisim>  
 {  
   public IletisimMap()  
   {  
     Table("Iletisim");  
     Id(x => x.Id).GeneratedBy.GuidComb();  
     DiscriminateSubClassesOnColumn("IletisimTip");  
     Map(x => x.Baslik);  
     Map(x => x.Icerik);  
   }  
 }  

 public class SMSMap : SubclassMap<SMS>  
 {  
   public SMSMap()  
   {  
     DiscriminatorValue(1);  
   }  
 }  
 public class MailMap : SubclassMap<Mail>  
 {  
   public MailMap()  
   {  
     DiscriminatorValue(2);  
   }  
 }  

Yukarıda oluşturulan yapıda Iletisim isimli bir ana sınıf ve bu sınıftan türeyen iki alt sınıf olan SMS ve Mail sınıfları bulunmaktadır. Kullanılan DescriminateSubClassesOnColumn metodu ile hangi alt sınıfın yaratılacağı belirlenir. Ayrıca belirlenmiş olan Discriminator değerleri ile iletişim tipi belirlenerek hangi alt sınıfın yaratılacağının Fluent NHibernate tarafından anlaşılması sağlanmış olur [4].

Yukarıda kurmuş olduğumuz yapı ile kalıtım sağlanmış olur ve discriminator kullanımının ne işe yaradığını da görmüş oluyoruz. Bu haftalık anlatacaklarım bu kadar, umarım faydalı bir yaz olmuştur hoşçakalın..

Kaynaklar 


[1]C# İle Kalıtım(inheritance)- Override ve Virtual Metodlar, http://www.ramazancelikkaya.com/makaleOku/CSharp/131/C, Mayıs 7, 2015.

[2]Inheritence – Miras Alma (Kalıtım), http://www.ismailgursoy.com.tr/inheritence-miras-alma-kalitim/, Mayıs 8, 2015.

[3]Inheritance mapping strategies in Fluent Nhibernate, http://www.codeproject.com/Articles/232034/Inheritance-mapping-strategies-in-Fluent-Nhibernat, Mayıs 8, 2015.

[4]Fluent NHibernate - Table Inheritance - Discriminators, http://www.philliphaydon.com/2011/08/fluent-nhibernate-table-inheritance-discriminators/, Mayıs 9, 2015.

1 Mayıs 2015 Cuma

Convention Sınıflarının Yeniden Yazılması


Herkese merhabalar.

 Bugün sizlere, önceki yazılarda bahsetmiş olduğum convention sınıflarını nasıl kendimize göre değiştirebileceğimizden bahsedeceğim. Öncelikle convention sınıflarının ne olduğunu bir hatırlayalım. Convention sınıfları, tablo ve kolon isimlendirmelerini yaparken bize yardımcı olan default sınıflardır. İsimlendirme sınıflarından bazılarını hatırlayalım. Önceki haftalarda detaylı bir şekilde anlattığım için sadece bazı isimlerini hatırlatacağım [1].

  • ColumnNullabilityConvention
  • PrimaryKeyNameConvention
  • StringColumnLengthConvention
  • IClassConvention
  • IIdConvention
  • IHasManyConvention
  • IReferenceConvention 

 
      İsimlendirme sınıflarını neden değiştirelim ki dediğinizi duyar gibiyim. Örneğin; StringColumnLengthConvention'ın default sınıfında, string tipindeki kolonun uzunluk sınırı belirtilmediyse bu sınıf sayesinde otomatik olarak uzunluk 100 olarak atanır [1]. Eğer bu uzunluğun 100 değil de 50 olmasını istiyorsanız, default olan isimlendirme sınıfını kendinize göre uyarlayıp bu yapıyı kullanabilmeniz gerekiyor.

    İsimlendirme sınıfları(conventions), birçok interface ve ana sınıflar kullanılarak oluşmuş olan sınıflardır [2]. Bu sınıfların her birinde Apply metodu tanımlanmıştır. Bu metot, isimlendirme sınıfının çeşidine göre parametreler almaktadır [3]. Bu metot, eşleştirmelerinize yapmış olduğunuz değişimin yapıldığı yerdir [2]. Eşleştirme sınıfınızın yapısını oluşturduktan sonra default olan isimlendirme sınıfları uygulanır. Aşağıdaki örnek ile isimlendirme sınıflarının mantığını daha iyi anlayacaksınız.

 public class KisiMap : ClassMap<Kisi>  
 {  
  public KisiMap()  
  {  
   Id(x => x.Id);  
   Map(x => x.Ad)  
    .Column("TumAd")  
    .Length(100);  
   Map(x => x.Yas);  
  }  
 }  

Yukarıda belirlemiş olduğumuz mapping sınıfımıza göre, isimlendirmemizin akış şeklini açıklayacağım; kullanmış olduğunuz high-level metodlara bakarak, convention sınıfı mapping sınıfınızın Kisi sınıfı olduğunu, Ad ve Yas olarak iki özelliğinizin olduğuna karar verir. Daha sonra, convention sınıfları, kolon isimleri, uzunluğu gibi değerlere uygulanır [2]. Convention(isimlendirme) sınıflarımızın çalışma yapısını anladıktan sonra, gelin kendi örneğimize bir bakalım.

 public class LowercaseTableNameConvention : IClassConvention  
 {  
  public void Apply(IClassInstance instance)  
  {  
   // değiştirme yapılacak yer..  
  }  
 }  

Yukarıdaki kod ile tablo ismimizi belirleyebilmemiz mümkün; ancak Apply metodunun içerisine tablo isimlerimizin ne yapıda olacağını yazmalıyız.

 public void Apply(IClassInstance instance)  
 {  
  instance.Table("tbl_" + instance.EntityType.Ad);  
 }  

Yukarıda gördüğünüz üzere, IClassInstance interface'i sayesinde Table metodunu kullanarak convention sınıfımızın tablo ismini kendimize göre yazmak bu kadar kolay [2]. Dilediğiniz convention sınıfını Apply metodu sayesinde yukarıdaki şekilde kendinize göre uyarlayabilirsiniz.

Bu haftalık anlatacaklarım bu kadar. Bir sonraki yazıda buluşmak üzere, hoşçakalın..


Kaynaklar


[1] Fluent NHibernate conventions-examples, http://marcinobel.com/index.php/fluent-nhibernate-conventions-examples/, Nisan 27, 2015.

[2] Conventions, https://github.com/jagregory/fluent-nhibernate/wiki/Conventions, Nisan 27, 2015.

[3] Changing The FluentNHibernate Id Conventions, http://candland.net/2009/09/14/changing-the-fluentnhibernate-id-conventions/, Nisan 27, 2015.