Sansür, bir toplumun kendine olan güvensizliğini yansıtır ve otoriter rejimlerin belirgin bir özelliğidir.

--Potter Stewart

30.12.2010

Spring ile Hibernate Annotation Kullanılan Entity Sınıfların Otomatik Algılanması

Veri erişim katmanında JPA standartını kullanırken annotation ile tanımladığımız entity sınıflarımızın algılanması, proje ayağa kalkarken otomatik gerçekleştirilir. Araya JPA standartını sokmak yerine doğrudan Hibernate çatısını kullanmak istediğimizde annotationlarla tanımlanmış bu entity sınıflarının algılanabilmesi için kullanılagelen yaygın yöntem ya hibernate.cfg.xml içersinde bu sınıfları algılatmak ya da her bir entity sınıfını Spring'in Hibernate entegrasonu için kullanıma sunduğu AnnotationSessionFactoryBean tanımı içinde tek tek belirtmektir:

<bean id="sessionFactory"
 class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
 <property name="dataSource" ref="${dataSourceType}" />
 <property name="hibernateProperties">
  <props>
   <prop key="hibernate.dialect">${hibernate.dialect}</prop>
   <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
   <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
   <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
  </props>
 </property>
 <property name="annotatedClasses">
  <list>
   <value>com.prime.ExampleClass1</value>
   <value>com.prime.ExampleClass2</value>
  </list>
    </property>
</bean>


annotatedClasses'ın bu şekilde kullanımı entity sınıf sayısı arttıkça sıkıntı yaratmaya başlayabilir. Bunun yerine aynı Spring bean'in packagesToScan değişkeni uygun paket yapısıyla kurarak uzun uzadıya sınıf tanımları yapmaktan kurtulabilirsiniz:

<property name="packagesToScan" value="com.prime" />

ya da

<property name="packagesToScan">
 <list>
  <value>com.prime.package1.model</value>
  <value>com.prime.package2.model</value>
 </list>
</property>

Hibernate annotation kullanan entitylerinizin otomatik algılanması için yukardaki tüm kullanımlara ek olarak proje classpath'inde javassist.jar kütüphanesi de bulunmalıdır..

21.12.2010

Spring - JSF Yeniden (JSF 2.0)

Blogta ziyaret edilen girdilere göz attığımda "Spring - JSF Bütünleştirmesi" yazımın son zamanlarda tekrar ziyaret edildiğini farkettim. Hazır geçen hafta da JTPD'nin eğitim seminerlerinde bu konular üzerine eğilmişken iki çatının entegrasyonunu, değişen yeteneklerini de dikkate alarak tekrar gözden geçirelim istedim.

Eski girdide bu iki çatıyı birbirleriyle anlaşır hale getirebilmek için JSF'ye variable resolver olarak Spring'in bize sunduğu DelegatingVariableResolver sınıfını tanıtmıştık. Bu sınıf iki çatı arasında bean aktarımlarını gerçekleştirmek için aktarımı yapılacak beani öncelikle JSF beanlerinde, bulamazsa Spring beanlerinde arıyordu. Benzer şekilde, önce Spring bean tanımlarına sonra da JSF bean tanımlarına bakan SpringBeanVariableResolver Spring sınıfını da JSF 1.1 ve 1.2 sürümlerinde kullanabiliriz.

JSF 1.2+ sürümlerinde ise variable resolver kullanımı yerini ELResolver'a bırakıyor:

<faces-config>
  <application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
  </application>
</faces-config>


Spring ile JSF'i bu şekilde ilişkilendirdikten sonra eski yazıdaki örneği bu sefer JSF 2.0'ın annotationlarını kullanarak Spring beanini JSF bean tanımı içine aktarımını yapalım:

@ManagedBean(name="member")
@RequestScoped
public class Member {

 @ManagedProperty(value="#{memberService}")
 private MemberService memberService;

 // memberService getter/setter
}

Spring bean tanımını da @Service("memberService") ya da @Component("memberService") annotationlarını kullanarak da xml'e bulaşmadan MemberService sınıfı içinde yapabiliriz:

@Service("memberService")
public class MemberServiceImpl implements MemberService {
    // ...
}

Spring annotationlarının çalışması içinse Spring context xml tanımınına ya <context:component-scan base-package="com.prime.packname"></context:component-scan> satırını eklemeli ya da web.xml içerisinde Spring bean tanımlarını xml yerine annotation kullanarak yapacağımızı belirten gerekli düzenlemeleri yapmalıyız:

<web-app>
      <context-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
      </context-param>

      <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>com.prime.packageName</param-value>
      </context-param>
</web-app>


Bu işlemlerin ardından annotationlarla tanımladığımız Spring ve JSF beanlerini birbirine entegre olarak kullanabiliriz. Bol Javalar..

12.12.2010

JTPD'de JSF, Spring ve JPA Sunumları

Dün JTPD'nin düzenlediği Java eğitimlerinin 3. haftasında katılımcılara JSF, Spring ve JPA sunumları yapma fırsatım oldu. Sunumların ardından küçük örnekler yaparak da anlatılan konuları pekiştirmeye çalıştık. Her ne kadar bahsi geçen konuları detaylı incelemek için 4-5 saat gibi çok çok kısıtlı süremiz olsa da mümkün olduğunca bu çatılar (framework) bizlere neler vaat ediyor, yetenekleri neler ve birbirleriyle nasıl entegre edebiliriz konuları üzerinden hızlıca geçtik. Anlatılan konular katılımcılar için zaman zaman detaylı ve karmaşık olsa da beni sabırla dinledikleri için kendilerine çok teşekkür ederim. Umarım faydalı olabilmişimdir. Hazırladığım eğitim sunumlarına ve örnek projelere buradan erişebilirsiniz. Java kültürünü daha geniş kitlelere yaymaya çalışan JTPD derneğini de tebrik ediyorum..

6.11.2010

Introduce Null Object


Tasarım örüntüleri yazılımın yönetilebilirliği ve genişletilebilirliği için ulaşılmak istenen hedeftir. Sadece bu hedefi anlayıp uygulamaya çalışmak yerine, hedefe nasıl ulaşıldığını anlamak daha önemlidir. Refactoring yöntemleri, sizi ideal hedefe ulaştıran tasarımsal evrimi temsil eder[1]. Bu yöntemlerden bir tanesi de Null Objecttir.

Uygulama geliştirme esnasında bir metot sorgusu sonucu dönen nesnenin null olup olmadığının kontrolünü yapmak sıklıkla başvurduğumuz kontrollerden birisidir. Bu kontrolü unuttuğumuz da ise vay halimize, o ünlü NullPointerException hatasıyla uygulamamızın göçmesi kaçınılmaz olur.

İş mantığımızın gereksinimleri sebebiyle bir nesne için bu kontrolü sıklıkla tekrarlayarak null olma durumunda kodun alternatif davranışlar sergilemesi gerekebilir. Bu durum kaynak kodumuzun fazlaca tekrarlı kontrol deyimi içermesine ve Martin Fowler’ın Refactoring[2] kitabındaki deyimiyle kodun kötü kokular yaymasına sebep olacaktır. Böyle bir durumda uygulanması gereken refactoring (ben “kod adam etme” demeyi seviyorum) yöntemi Null Object olmalıdır.

Bir Null Object temel olarak gerçek nesneyle aynı metot imzalarına sahiptir. Metotları ise null olma durumunda varsayılan değerleri döndürecek, alternatif davranışları sergileyecek şekilde gerçekleştirilir.

Metot imzaları aynı olacağı için Null Object ya gerçek nesneden kalıtım (inheritance) yoluyla türetilecek ya da gerçek nesneyle ortak bir interfaceden geliştirilecek (implement) şekilde tasarlanabilir.


Kalıtım yoluyla yaratılan Null Object sınıfının, null olma durumunda alternatif davranışı sergileyecek metotları override etmesi gerekmektedir. Atasınıfa yeni eklenen metotların alternatif davranış için override edilmesinin unutulması hatalı işleyişe sebep olabilir. Interface gerçekleştirilerek yaratılan Null Object sınıfında bu risk söz konusu olmaz. Ama bu sefer yaratılan yeni sınıf içeriğinde alternatif davranış sergilemek zorunda olmayan diğer metotların gövdelerinin de barındırması gerekir. 
Bir diğer sıkıntı da geliştirim aşamasında değişmeye meyilli interface tasarımlarıdır. Yeni metot eklendikçe, metot çıkartıldıkça ya da metot imzaları değiştikçe Null Object sınıfını da değiştirmek gerekir. Bu soruna Kenan Sevindik, blogunda yazdığı “Mockito ile Null Object”[3] yazısında ilginç bir çözüm getiriyor. Joshua Kerievsky “Refactoring to Patterns”[1] kitabında Null Object yönteminin temel amacının kodu basitleştirmenin yanında kaynak kod satır sayısını düşürmesi gerektiğini, en azından aynı düzeyde tutması gerektiğinin altını çiziyor. Kaynak kod satır sayısı artıyorsa uygulanmamasını  tavsiye ediyor.

Null Object örüntüsünün varlığı null kontrollerinin yapılmayacağını garanti etmez. Null Object örüntüsünün kullanıldığından habersiz bir başka geliştirici null kontrolleri yapmaya devam edebilir dahası null olma durumunda işletilecek kod parçalarını iş mantığına ekleyebilir. Null Object nesnesini ve gerçek nesneyi davranış barındırmayan Nullable gibi boş bir interfaceten gerçekleştirmek geliştiricilerin dikkatini çekerek bu gibi problemlerin önüne bir nebze de olsa geçebilir. Boş bir interfaceten gerçekleştirmek yerine isNull() metotu içeren bir interface de ilerde ihtiyaç duyulabilecek olası bir null kontrolü için faydalı olur:


public interface Nullable {
 boolean isNull();
}
public class Customer implements Nullable {
 boolean isNull(){
  return false;
 }

   Plan getPlan(){
          doMoreThings();
  }
}
public class NullCustomer extends Customer {
 boolean isNull(){
  return true;
 }
 
  Plan getPlan(){
    return Plan.emptyPlan();
  }
}


Kaynak koda müdahale edemediğimiz durumlarda sadece Null Object davranışı olmayan bir interfaceten gerçekleştirilerek null kontrolü instanceof ile yapılabilir:


public interface Null { }
public class NullCustomer extends Customer implements Null{
//...
}
//...
if(customer instanceof Null) { }
//...



Null Object davranışı ve durumu değişmeyecek bir sınıf olduğu için çok fazla Null Object nesnesi yaratılma durumunda Singleton tasarım örüntüsü kullanılarak her yeni çağrıda yeni null sınıf yaratılmasının önüne de geçilebilir.

Artıları/Eksileri:
+ Null kontrolü tekrarları yapmadan, null hatalarının önüne geçer.
+ Null kontrollerinin sayısını en aza indirerek kodu basitleştirir.
- Sadece bir kaç null kontrolü kullanıldığı durumlarda kodu karmaşıklaştırır.
- Null Object gerçekleştirimi yapıldığından haberi olmayan bir geliştirici gereksiz null kontrolleri yazabilir.
- Yönetilebilirliği zorlaştırır. Gerçek sınıfa eklenen yeni metotlar için Null Object sınıfı içinde override işlemi yapılmalıdır.



Bir örnekle konuya açıklık getirelim:

class SecmenKutugu {
 Vatandas vatandas;
 Vatandas getVatandas(){
  return vatandas;
 }
}
class Vatandas{
 public long getTCNo() { 
  //..
  }
 public Adres getAdres() { 
  //.. 
  }
 public Muhtar setMuhtar { 
  //..
  }
}

class Adres {
 public int getSokakNo() { 
  //.. 
  }
 // ...
}




Vatandas vatandas = secmenKutugu.getVatandas();
if(vatandas != null) vatandas.setMuhtar(Muhtar.getInstance());
//...
long tcNo;
if(vatandas == null) tcNo = 0;
else tcNo = vatandas.getTCNo();
//...
int sokakNo;
if(vatandas == null) sokakNo = 0;
else sokakNo = vatandas.getAdres().getSokakNo();
//..

Yukardaki örnekteki gibi tekrarlı null kontrolleri yapan kodumuz olsun. Bu kodu adam etmeye null testi yapmaya imkan sağlayan Null Object yaratmakla başlayalım. Böylelikle bahsettiğimiz gibi diğer geliştiricilerin de Null Object kullanıldığına dair dikkatini çekebiliriz:


interface Nullable {
 boolean isNull();
}
class Vatandas implements Nullable{
 
 static Vatandas newNull() {
                return new NullVatandas();
        }
        boolean isNull(){
  return false;
 }
 //...
}
class NullVatandas extends Vatandas {
 boolean isNull(){
  return true;
 }
}
Null değer dönebilecek yerlerde yarattığımız yeni Null Object nesnesini döndürelim:
class SecmenKutugu {
 Vatandas vatandas;
 Vatandas getVatandas(){
  return (vatandas == null)? Vatandas.newNull(): vatandas;
 }
}
Null kontrollerinin yapıldığı her bir iş mantığı için Null Object sınıfına null olma durumunda işletilecek alternatif metot kodunu ekleyelim ve null kontrollerini kaldıralım. Ayrıca her değişiklikte kodun davranışının değişmediğini test etmekte yarar var. Tüm değişikliklerin sonunda kodumuz şu şekilde olacak:
class NullVatandas extends Vatandas {
 public long getTCNo() {
  return 0;
 }
 public Muhtar setMuhtar(Muhtar muhtar) { }
 public Adres getAdres() {
  return Adres.newNull();
 }
}
class NullAdres extends Adres {
 public int getSokakNo(){
  return 0;
 }
 //..
}
 

Vatandas vatandas = secmenKutugu.getVatandas();
vatandas.setMuhtar(Muhtar.getInstance());
//...
long tcNo = vatandas.getTCNo();
//...
int sokakNo = vatandas.getAdres().getSokakNo();
//..

Yukarıdaki örnekte Adres sınıfı için de bir
Null Object yazma gerekliliğimiz dikkatinizi çekmiştir. Sınıfın başka bir sınıfa delege ettiği metotlar için null sınıfın da metotu delege edeceği yeni null sınıflar yazılır.



Null Object yöntemi nesnenin null davranışını modellemek için kullanılabileceği gibi aynı zamanda nesnenin varsayılan davranış sergileyecek farklı senaryoları için de (Örk: NullVatandas, UnknownVatandas, PrivateVatandas vb.) kullanılabileceğini belirterek konumuzu sonlandıralım.


Kaynaklar:
1. Joshua Kerievsky - Refactoring to Patterns
2. Martin Fowler - Refactoring: Improving the Design of Existing Code
3. Kenan Sevindik - http://ksevindik.blogspot.com/2010/01/mockito-ile-null-object.html

14.08.2010

Popüler Programlama Dilleri

Bu site programlama dillerini çeşitli kriterleri dikkate alarak populerliğine göre aylık olarak sıralıyor. Java uzunca bir süredir ilk sırada. Dünyadaki programlama dili akımlarını takip etmek için güzel bir kaynak. Örneğin Ağustos-2010 tarihinde son zamanların popüler programlama dili Python hafif bir düşüşe geçmişken Objective-C atakta. Google'ın geliştirdiği Go programlama dili sağlam bir çıkış yaparak ilk 20 içine girerken yılların Smalltalk dili 50. sıradan da aşağılara düşmüş:

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

İyi Javalar..

4.07.2010

Eşli Programlama

Eşli programlama (Pair Programming) iletişimi, eşler arasında işbirliğini ve dolayısıyla öğrenmeyi temel alan program geliştirme yöntemidir. Eşlerden biri "Sürücü (Driver)" rolünü diğeri ise "Yönlendirici (Navigator)" rolünü üstlenir. Aynı bir yarış arabasındaki pilot/yardımcı pilot yardımlaşmasındaki gibi, Sürücü kodun yazımı, yazım hatalarının denetimi, API'lerin çağırımı gibi konularla ilgilenirken Yönlendirici de yapılan işin doğruluğu, gereksinimler, alternatif yöntemler, bir sonraki adım, vb. konulara yoğunlaşır. Eşler büyük resmi, birbirlerinin eksiklerini tamamlayarak daha iyi ele alırlar. Olası hatalar büyük oranda ortaya çıkma aşamasında ele alınır ve çözülür.

Niclas Nilsson ve Hans Brattberg eşli programlamayı, yapılması ve yapılmaması gerekenleri, eşli programlamanın avantajlarını küçük tiyatrolarla destekleyerek anlatmışlar. Hoş bir sunum tarzı olmuş: The Pair Programming Show

18.06.2010

Java Dergisi..

Java Dergisi'nin yayın hayatına başlaması Türkiye yazılım dünyası için güzel bir gelişme oldu... Kaliteli ve doyurucu bir içeriğe sahip olmasının yanında çok kaliteli bir baskıya da sahip olan dergiye emeği geçenlere içten bir teşekkürü borç bilirim. Özellikle de bu dergi için ön ayak olan Özcan Acar'a...

Gerçek bir yazılım içeriği sunması açısından Java'ya gönül verenlerin, Java'ya adım atmak isteyenlerin ellerinden düşürmeyecekleri bir dergi. Derginin önerilerimizle daha da iyi olacağını düşünüyorum. Alınası, bol bol okunası...

Tekrar teşekkürler.

Tekrar Yayında..

Evet askerlik bitti...

17 Mayıs itibari ile askerliği bitirip özlediğim sivil hayata dönüş yaptım. Askerlik ile ilgili düşünceleri dost meclisinde dile getiriyoruz. Burada sivil hayatımdaki değişiklikleri paylaşayım.

Her şey değişti... İşim, evim, yaşadığım şehir... Bundan sonraki hayatımı paylaşacağım müstakbel eşimin isteği sebebiyle İstanbul'a taşındım. Bu nedenle 9 senelik arkadaşları, güzel anıları paylaştığım dostları üzülerek Ankara'da bıraktım. Ama her fırsatta bir araya geleceğimizden hiç şüpheleri olmasın. Bunun yanında bir çok şey öğrendiğim, aralarında bulunmaktan mutluluk duyduğum Innova Ankara ailesinden de ayrılmak zorunda kaldım. Prime Teknoloji ailesine katkı sağlamaya, yeni şeyler öğrenmeye, öğrendiklerimizi aktarmaya çalışacağım.

Askerlik ve askerlikten sonra tüm bu değişiklikleri yönetmek, bir yandan da evlilik hazırlıkları yapmak zamanımın çoğunu götürdüğü için özlediğim mesleğime, uğraşmayı sevdiğim Java dünyasına dönmemi geciktirdi. Belirsizliklerin yavaş yavaş ortadan kalkması, işlerin planlanması sonucu tekrar kendime ve Java'ya vakit ayırmaya başlıyorum.

Umarım bundan sonra da her şey güzel ve gönlümüzce olur...