Strategy Pattern ve ExcelRunner Projesi

Strategy pattern mantığını anlatmak için stajda yaptığım  bir örneği yazıyorum.

Kullanıcı programı açtığında 3 adet buton karşısına çıkmalıdır. Bu butonlar Office 2003, Office 2007 ve Open Office olmak üzere 3 ayrı programı temsil eder. Bu butonlara basıldığında ilgili butonun programı çalıştırılarak bir excel dosyası açılmalıdır. Açılan bu dosyada bir array içerisinde tutulan isim ve yaş girdileri olmalıdır.

Proje küçük ve basit bir uygulama gibi görünse de strategy pattern kullanımı için idealdir. Strategy pattern hakkında fikir sahibi olunmadığında butonların actionPerformed metodunda kullanılacak if döngüleriyle sorun halledilebilir ya da her buton için ayrı olarak tanımlanacak actionPerformed metodlarında ayrı implementasyonlar yazılabilir. Ama burada can alıcı soru “İleride Office 2010 gibi bir uygulama çıktığında bunun projeye entegrasyonu en kolay nasıl sağlanabilir?” olmalıdır. Bir başka deyişle “Bu işin yapılması için sağlanabilecek çözümler değişkenken nasıl bir dizayn yöntemi düşünülmelidir ki çözümler değişse bile programın modifikasyonu değişmesin?” olarak ifade edilebilir. Bu sorulara cevap veren Strategy patterndir.

Strategy pattern; main class da dahil olmak üzere 4 çeşit objeden oluşur. Burada programın konuşması interface ile olur; concrete classlara bağımlılık yoktur.

Strategy (Interface) : Söz konusu işi gerçekleştirecek olan classların bu işi yaparken kullanması gereken metodların deklare edildiği arayüzdür.

Concrete Strategy: Strategy interface implementasyonunu yapan classlardır. Office2003, Office2007 ve OpenOffice bu projenin concrete strategyleridir.

Context: Strategy interface ile arasında bir ‘has a’ ilişkisi vardır. Bu interface’in sahip olduğu metodları çağırır.

Main (Runner): Context classı ile arasında bir ‘has a’ ilişkisi vardır. Strategylerin yapması gereken işleri Context classı üzerinden yaptırır.

Kısaca işleyişi main class contexte istediği concrete strategy üzerinden erişir şeklinde tanımlayabiliriz. Görüldüğü gibi concrete strategy ne olursa olsun programın etkileşimde olduğu class Context classıdır ve concrete strategy’nin değişmesi bu etkileşimi herhangi bir şekilde değiştirmez. Ayrıca Office2010 gibi bir seçenek eklendiğinde yapılması gereken tek şey main classın contexte Office2010 ile erişmesini sağlayacak kodu sisteme eklemektir.

Projenin classları arasındaki ilişkiden sonra iki soru daha öne çıkmaktadır:

1-) Excel dosyasına veri girişi nasıl sağlanacaktır? Java dilini kullanarak excel dosyalarına erişim yapılmasını sağlayan çeşitli open source frameworkler bulunmaktadır. Bunlardan biri seçilerek veri girişi sağlama noktasındaki sıkıntı aşılabilir.

2-) Sistemde excel programı nasıl çalıştırılabilir? Javada harici bir process oluşturma işlemi kolaydır. Fakat asıl sıkıntı excel programının kurulu olduğu yolu bilmek ve oradan execute etmektir. Bunun için yöntem ileride düşünülecektir.

İnternette ücretsiz olarak yayınlanan open source java excel frameworkleri Apache POI ve JExcel proje için uygun bulunmuştur. JExcel kullanımına karar verilmiştir. JExcel, jxl.jar dosyası indirilip projeye kütüphane olarak eklendikten sonra geliştirmeye başlanmıştır. Dosyaya yazılacak veriler fields adıyla String[][] tipinde tanımlanmıştır. “sample.xls” adında bir dosya oluşturulup bu dosyanın içine veri girişi yapılmalıdır. Bunu yapan objeler şunlardır:

WritableWorkbook: jxl.write.WritableWorkbook objesidir. jxl.Workbook objesinin static bir metodu olan ve parametre olarak java.io.File tipinden bir değişken alan createWorkbook isimli metod kullanılarak oluşturulur.

WritableSheet: WritableWorkbook oluşturulduktan sonra bunun üzerinde çalışma yapılabilmesi için bir sayfa oluşturulmalıdır. Bu da WritableWorkbook objesinin, parametre olarak sayfa adını temsil eden bir String ve tamsayı alan, createSheet metoduyla gerçekleştirilir.

Bundan sonra yapılacak işlem WritableSheet objemize dizimizi yazdırmaktır. Bunun için bir for döngüsünde şu kod kullanılır: (i, for döngüsünün değişkeni olup sıfırdan fields.length’e kadar dönülür)

writableSheet.addCell(new Label(0,i,fields[i][0]));

writableSheet.addCell(new Label(1,i,fields[i][1]));

Burada Label objesinin kullanılma sebebi en kısa yoldan excel hücresi oluşturmaktır. Diğer hücre oluşturma yöntemlerinde bu hücrelerin renkleri gibi pek çok özelliklerinin tanımlanmasını gerektiren format objeleri kullanılması gerektiğinden Label kullanılmıştır.

Yukarıdaki kod for döngüsü içerisinde çalıştırıldıktan sonra işlem ciddi anlamda sona ermiştir. writableWorkbook objesinin write metodu çağırıldıktan sonra close metodu da çağırılarak söz konusu excel dosyasının oluşumu tamamlanmış olur.

Burada dikkat edilmesi gereken bir diğer husus da exception’ların handle edilmesidir. Bunu yapmak amacıyla yukarıdaki işlemlerin anlatıldığı kod bloğu try-catch içerisine alınmıştır. Handle edilmesi gereken exceptionlar WriteException ve IOException olarak sıralanabilir.

Projenin son aşamasında yapılması gereken ise butonuna basılan excel programının sistemde kurulu olup olmadığını anlamak ve parametre olarak “sample.xls” dosyasını vererek programın açılmasını sağlamaktır.

Javada harici bir process oluşturmak için kullanılan yöntemler araştırılmıştır. Araştırmalar sonucunda javanın Runtime özelliği ile bunun yapılabileceği öğrenilmiştir. Runtime özelliğinin statik bir metodu olan ve sistemin çalışma anındaki Runtime objesini döndüren getRuntime() metodu kullanılarak Runtime objesi elde edilmiş ve bu objenin exec(String command) metodu ile de işlemin gerçekleştirilebileceği görülmüştür.

Runtime objesinin exec metoduna nasıl bir command stringi girilmelidir sorusuna cevap aranmıştır. Command stringi hem söz konusu Office uygulamasının yolunu hem de parametre olan “sample.xls” dosyasının yolunu içermelidir. Office uygulamasının yolunu bulmak için yapılacak en doğru şeyin system registry kayıtlarına bakmak olduğu anlaşılmıştır. Fakat Vista gibi işletim sistemlerinde registry erişimi yapmak için administrator yetkisi gerektiğinden bu yolun default yol olarak kullanılması uygun görülmüştür. Buna göre:

Runtime.getRuntime().exec(“C:\\Program Files\\Microsoft Office\\Office12\\excel.exe”);’in sistemdeki Office 2007 kurulumunun excel dosyasını çalıştırması beklenmiştir.

Default kurulum üzerinden programa ulaşıldığı göz önüne alınırsa geriye “…excel.exe ..” ifadesinde iki nokta ile belirtilen ve “sample.xls” dosyasının yolunu veren stringi bulmak kalmıştır. Bunun için de String filename = System.getProperty(“user.dir”) + “\\sample.xls”; koduyla bu yola erişilmiştir. Burada System.getProperty(“user.dir”) şu anda çalışılan dizini vermektedir. Bir çeşit “pwd” komutu olarak da nitelendirilebilir.

Yukarıda anlatılan sample.xls dosyasını oluşturmak ve excel dosyasını çalıştırmak takdir edileceği üzere strategy objelerinin görevidir. Office2003, Office2007 ve OpenOffice classlarında bu implementasyonlar yazılmıştır.

Main classta bulunan Context classının sahip olduğu Strategy arayüzü  her butonun actionPerformed metodunda değiştirilmekte ve yine aynı metodda işi yapan fonksiyonlar çağırılmaktadır.

Kaynak : Staj defterim :)


About this entry