SİTE
İÇİ ARAMA |
|
Blogroll |
|
|
|
Null Object Pattern |
|
Gönderiliyor lütfen bekleyin... |
|
|
Genellikle yazığımız kodların içinde bir nesnenin null olup olmadığının kontrolünü hepimiz olcukça fazla yapıyoruz .Kendim için söyleyeyim null görünce kodun o kısmında ne zaman hata çıkacak diye beklerim genelde. Örneğin veritabanından herhangi bir nesne çekmeye çalıştığımızda önce gelen nesnenin boş olup olmadığını kontrol ederiz ardından boş değilse ona ait çeşitli işlemler gerçekleştiririz. Kodumuzun içinde bu tür null değerlerini fazlaca kullandığımızda hem gereksiz kod tekrarı ve hem hata eğilimi artar hemde kodumuzun okunulabilirliği oldukça azalır. Bu gibi durumlarda uygulayabileceğimiz çözüm için nesneye yönelik programlama dünyasında oldukça fazla kullanılan Null Object tasarım kalıbını ufak bir örnekle anlatacağım.
Örnek olarak aşağıdaki gibi bir öğrenci sınıfımız olsun veritabanından bu öğrenci nesnesini alalım. Ardından öğrencinin sınıf içi kanaat notu 5 ise öğrencinin yıl sonu ortalamasını 1 puan arttıralım.Ayrıca programımızın başka bir yerinde herhangi bir öğrencinin işlemine ait log tutalım. Log tutarken öğrenci numarasını ve öğrenci adını log sistemimize yazsın. Ve aradığımız numaraya ait öğrenci yoksa log olarak numarasını ve bu numaraya ait kayıt olmadığını yazsın.İlginç bir programcık oldu ama makale için idare edin. Kötüde olsa bu örneği uydurana kadar baya bir kafa patlattım:) Örnek log kayıtlarımız şu yapıda olsun :
010201003 Cihat Altuntaş
010201010 Muharrem Çetinkaya
010201445 Kayıt yok
............................
Bu işlemleri aşağıda gördüğümüz şekilde yazdığımız sınıflarla kolayca yapabiliriz.
using System;
namespace Makale
{
public class Ogrenci {
private string ad;
private string numara;
private int davranisNotu;
private int yilSonuNotu;
public Ogrenci()
{
}
public virtual string Ad
{
get { return ad; }
set { ad = value; }
}
public virtual string Numara
{
get { return numara; }
set { numara = value; }
}
public virtual int DavranisNotu
{
get { return davranisNotu; }
set { davranisNotu = value; }
}
public virtual int YilSonuNotu
{
get { return yilSonuNotu; }
set { yilSonuNotu = value; }
}
public virtual void NotArttir()
{
yilSonuNotu++;
}
}
}
|
Veritabanından öğrenci getiren sınıfımız aşağıdaki gibi olsun
public class OgrenciDB
{
.............
public OgrenciDB()
{ }
public static Ogrenci GetOgrenci(string numara)
{
return db.GetOgrenci(numara);
}
}
|
Bu işlemleri yaptığımız kodumuzda aşağıdaki gibi olsun.
public static void Main()
{
string numara ="010201003"
Ogrenci ogrenci = OgrenciDB.GetOgrenci(numara);
if (ogrenci!=null && ogrenci.DavranisNotu==5)
{
ogrenci.NotArttir();
}
if (ogrenci!=null)
{
Logger.log(numara+" "+ogrenci.Ad);
}
else
Logger.log(numara+" "+"Kayıt Yok");
}
|
Gördüğünüz gibi programımızda ufak tefek işlemler için bile birçok null kontrolü yaptık. Ve bu işlemlerin daha da uzayacağını düşünürsek programımızın birçok yerinde null kontrolü yapmak zorunda kalacağız ve bu programın okunabilirliğini ve hata eğilimini arttıracak.
Null Object Tasarım kalıbına göre bu problemi şöyle çözebiliriz. Normal işlemlerimiz için yukarıda gördüğümüz Ogrenci sınıfını kullanırız ve null değerleri için basit bir NullOgrenci sınıfımız olsun ve bu sınıf Ogrenci sınıfımızdan türesin. Ve bu sınıf bize boş olan yada olmayan öğrencinin davranışını simgelesin. Yani yukarıda gördüğümüz kodda boş olmayan öğrencinin null olmadığı kontrol ediliyor ve ogrenci.NotuArttir() metodu çağırılıyor. Tabi gelen öğrenci eğer null ise hiçbir Not arttırma işlemi yapmayacak ayrıca gelen öğrencinin adı olarakta bize "Kayıt Yok" değerini verecek. Null Object tasarım kalıbına göre yeniden düzenlediğimiz sınıflarımızın yapısını şekildeki gibi görebiliriz.
public class NullOgrenci:Ogrenci
{
public NullOgrenci() { }
public override void NotArttir()
{}
public override string Ad
{
get { return "Kayıt Yok"; }
set { }
}
}
|

Bu aşamadan sonra veritabanından öğrenci getiren sınıfımız olan OgrenciDB eğer girilen numarada öğrenci yoksa NullOgrenci geri döndürecek öğrenci null değilse normal öğrenci döndürecek. Böylece ana programımızda bundan sonra null kontrolü yapmak zorunda kalmayacağız çünkü NullOgrenci sınıfı ile varsayılan işlemleri ya da olmayan öğrenci için yapılacak işlemleri bizim için yapıyor. OgrenciDB sınıfımızın kodlarını aşağıdaki gibi düzeltelim.
public class OgrenciDB
{
private static readonly NullOgrenci nullOgrenci =new NullOgrenci();
public OgrenciDB() { }
public static Ogrenci GetOgrenci(string numara)
{
if (db.GetOgrenci(numara))!=null)
{
return db.GetOgrenci(numara);
}
else
{
return new nullOgrenci;
}
}
}
|
Yeni tasarımımızdan sonra ana programımızın nasıl sadeleştiğini görebiliriz.
public static void Main()
{
string numara = "010201003";
Ogrenci ogrenci = OgrenciDB.GetOgrenci(numara);
ogrenci.NotArttir();
Logger.log(numara+" "+ogrenci.Adi);
}
|
Burada yeni tasarımımız hakkında birkaç şey daha söylenebilir. Bu tasarım kalıbının en büyük avantajı sınıfları kullananların null kontrolü ya da Exception kontrolü yapmaktan kurtulmasıdır. Tabi bunu kullanırkende dikkatli olmalıyız. Mesela kontrol sırasında verilen numarada bulunan öğrencilerin sayısını bir değişkende tutmak istiyorsak bu tasarım kalıbını kullandığımızda istenmeyen hatalarla karşılaşabiliriz. Benimde kullanırken rahatsız olduğum şeylerden biride önemli ölçüde küçükde olsa birçok NullObject sınıfı kodumuzdaki sınıf sayısını oldukça arttırmasıdır.Bu gibi durumlar için gelende inner class olarak NullObject sınıflarını kodlayabiliriz seçim size kalmış.Ayrıca OgrenciDB sınıfımızda NullOgrenci sınıfından static bir değişken kullanmamızın sebebi her defasında null değeri için yeni bir NullOgrenci oluşturmamıza gerek olmamasıdır. Umarım makale faydalı olmuştur. Vaktim oldukça önemli bulduğum Tasarım Kalıpları, Tasarım prensipleri ,Nesneye yönelik tasarımla alakalı makaleler yazmaya çalışacağım.
Hepinize iyi çalışmalar.
M. Cihat Altuntas
mcaaltuntas@hotmail.com
Makale:
Null Object Pattern C#, Visual C# ve .NET Cihat Altuntaş
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|
|