Oca 25

Java 1.5 ve Genel Tipler (Generic Types) - Bölüm 2

Pzt 25 Oca 2010 10:38:35 | 0 yorum
Java 1.5 ile gelen yenilikler içerisinde bulunan Genel Tipler ile bazı kod yazma pratiklerimizi değiştirmek ve kendimizi geliştirmek zorunda kaldık. Data Access Object ve Service gibi Üst Seviye Tasarım Kalıplarında (Enterprise Design Patterns), Java Torbalarında (Collections & Map) çok sık kullanır olduk. Tasarımsal olarak getirdiği faydalar olduğu gibi kötü kullanımda da kod okunabilirliliğini azaltmaktadır. Gelin Genel Tipler'in nasıl kullanıldığını bir bakalım...  Yazının diğer bölümleri : Bölüm-1
[--split--]

NesneHavuzu Sınıfı


public class NesneHavuzu<T extends Yedeklenebilir>
     implements Havuz<T> {
    
     private Vector<T> havuz = new Vector<T>();


     /* (non-Javadoc)
      * @see com.articles.generics.objectcaching.Havuz#doldur(java.lang.Class)
      */
     public void doldur(Class<T> clazz) throws NesneYaratmaHatasi {
           this.doldur(clazz, 5);      
     }
    
     /* (non-Javadoc)
      * @see com.articles.generics.objectcaching.Havuz#doldur(java.lang.Class, int)
      */
     public void doldur(Class<T> clazz, int adet)
throws NesneYaratmaHatasi {


           try {
                 for(int sayac=0; sayac<adet; sayac++){
                       this.havuz.add(clazz.newInstance());
                 }
           } catch (InstantiationException e) {
                 NesneYaratmaHatasi ex =
new NesneYaratmaHatasi(clazz, e.getStackTrace());
                 throw ex;
           } catch (IllegalAccessException e) {
                 NesneYaratmaHatasi ex =
new NesneYaratmaHatasi(clazz, e.getStackTrace());
                 throw ex;
           }
     }
    
     /*
      * (non-Javadoc)
      *
      * @see com.articles.generics.objectcaching.Pool#pull()
      */
     public T cek() {
           T object = havuz.remove(0);
           return object;
     }


     /*
      * (non-Javadoc)
      *
      * @see com.articles.generics.objectcaching.Pool#push(com.articles.generics.objectcaching.CachableObject)
      */
     public void koy(T object) {
           havuz.add(object);
     }


     /* (non-Javadoc)
      * @see com.articles.generics.objectcaching.Havuz#bos()
      */
     public boolean bos() {
           return this.havuz.isEmpty();
     }}


NesneHavuzu sınıfına dikkat edersek :  Havuz arayüzündeki tip parametresi
<T extends Yedeklenebilir>  burada da mevcut. Neden böyle?  Bakalım:


NesneHavuzu sınıfında <T extends Object> tanımını kullanıp derlemek istediğimizde :
şeklinde bir uyarı ile karşılaşırdık. Bu uyarıda NesneHavuzu sınıfı tanımlamasındaki tip parametresi, Havuz arayüzünün beklediği tip parametresinin sınırları dışında oluduğu belirtilmektedir.

NesneHavuzu sınıfında <T extends X_Nesne> tanımını kullanıp derlemek istediğimizde herhangi sorun ile karşılaşmayız çünkü T tip parametresi Havuz arayüzünün beklediği sınırlar yani Yedeklenebilir arayüzünün alt hiyerarşisi içerisindedir.


Peki Havuz arayüzünün tanılamasını public interface Havuz <T> şeklinde değiştirdiğimiz de ne olur? Birşey olmaz çünkü böyle yaparak Havuz arayüzü üzerindeki kısıtlamayı kaldırıp bu arayüzü her tipten yapı için çalışır duruma getirmiş oluruz, standart Java paketi içerisindeki torba (Hash, List ...) yapılarında olduğu gibi.


Şimdi de şöyle bişey deneyelim. Havuz arayüzünü eski haline getirelim ama bu sefer NesneHavuzu sınıfı tanımını NesneHavuzu<T> implements Havuz<T> şeklinde değiştirelim. Derlemek istediğimiz de


<T extends Object> örneğimizde olduğu gibi yine aynı nedenden dolayı derleme zamanında uyarı  alırız.

Peki alt hiyerarşi sınırlandırması için bir tanımlama mevcutken üst hiyerarşi sınırlandırması için bir tanımlama mevcut mu?  <T super Yedeklenebilir> Yedeklenebilir arayüzünün üst hiyerarşisi için sınırlama yapılır.

Şimdiye kadar yazmış olduğumuz yapıların testini gerçekleştirelim.


public class HavuzTest extends TestCase {
     private X_Nesne x_n1 = new X_Nesne();
     private X_Nesne x_n2 = new X_Nesne();
     private Y_Nesne y_n1 = new Y_Nesne();
     private Y_Nesne y_n2 = new Y_Nesne();
    
     Object obje_1 = new Object();
    
     private NesneHavuzu<X_Nesne> x_havuz = new NesneHavuzu<X_Nesne>();
     private NesneHavuzu<Y_Nesne> y_havuz = new NesneHavuzu<Y_Nesne>();
     private NesneHavuzu<Yedeklenebilir> genel_havuz = new NesneHavuzu<Yedeklenebilir>();
    
     public void testCek() {
           X_Nesne x_nesne_1 = x_havuz.cek();
//          Y_Nesne x_nesne_2 = x_havuz.cek(); Derleme hatasi verir
           Y_Nesne y_nesne_1 = y_havuz.cek();
          
          
//          Cek yordami Yedeklenebilir tipinde değer dönerken
//          biz X_Nesne tipinde bekliyoruz.
//          X_Nesne x_nesne_3 = genel_havuz.cek();
          
           X_Nesne x_nesne_3 = (X_Nesne) genel_havuz.cek();
          
     }


     public void testKoy() {
           x_havuz.koy(x_n1);
           x_havuz.koy(x_n2);
//          x_havuz.koy(y_n1); Derleme hatasi verir
          
           y_havuz.koy(y_n1);
           y_havuz.koy(y_n2);
          
           genel_havuz.koy(x_n1);
           genel_havuz.koy(y_n1);
    
//          x_havuz.koy(obje_1);         DERLEME HATASI
//          y_havuz.koy(obje_1);         DERLEME HATASI
//          genel_havuz.koy(obje_1);     DERLEME HATASI
     }
}


HavuzYoneticisi Arayüzü

public interface HavuzYoneticisi {
    
<T extends Yedeklenebilir> void nesneKoy(T nesne) throws NesneYaratmaHatasi;
    
<T extends Yedeklenebilir> T nesneCek(Class<T> clazz) throws NesneYaratmaHatasi;
    
<T extends Yedeklenebilir> void havuzuKontrolEt(Class<T> clazz) throws NesneYaratmaHatasi;
}

Burada dikkat etmemiz gereken, arayüzü değil arayüz içerisindeki yordamları genelleştiriyor olmamız. <T extends Yedeklenebilir> tip parametresi korunarak yine hiyerarşi sınırlandırması yapmış oluyoruz. Eğer HavuzYoneticisi arayüzünü de <T extends Yedeklenebilir> tip parametresi ile genelleştirmiş olsaydık sadece tek tip bir yapı için çalışıyor hale gelirdi. Tıpkı Havuz arayüzü gibi :

           NesneHavuzu<X_Nesne> x_havuz = new NesneHavuzu<X_Nesne>();


NesneHavuzuYoneticisi Sınıfı

public class NesneHavuzuYoneticisi implements HavuzYoneticisi {


     private Map<Class<? extends Yedeklenebilir>,
Havuz<? extends Yedeklenebilir>>
havuzMap = new HashMap<
Class<? extends

Yorum




ya da
CAPTCHA Images