Possible bug in Hibernate XML based mapping when using properties element

Assume you have a Person with firstName and lastName properties, and a subclass of it called as Vet. You will have hbm.xml mapping files with the following content.

Person.hbml.xml

<hibernate-mapping>
<class name="com.javaegitimleri.petclinic.model.Person"
table="persons"
abstract="true">
<cache usage="read-write" />
<id name="id" column="ID" access="field">
<generator />
</id>
<version name="version" column="VERSION" type="integer"
access="field" />
<properties name="firstAndLastName" unique="true">
<property name="firstName" column="FIRST_NAME"
type="string" />
<property name="lastName" column="LAST_NAME"
type="string" />
</properties>
</class>
</hibernate-mapping>

Vet.hbm.xml

<hibernate-mapping>
<joined-subclass name="com.javaegitimleri.petclinic.model.Vet"
extends="com.javaegitimleri.petclinic.model.Person"
table="vets">
<key column="ID"/>
</joined-subclass>
</hibernate-mapping>

If you run a HQL like “from Vet v where v.lastName = ‘Doe’“, you will have an error indicating that LAST_NAME column not found in VETS table. Here is the SQL generated from this query in H2 database.


select
vet0_.ID as ID72_,
vet0_1_.VERSION as VERSION72_,
vet0_1_.FIRST_NAME as FIRST3_72_,
vet0_1_.LAST_NAME as LAST4_72_
from
vets vet0_
inner join
persons vet0_1_
on vet0_.ID=vet0_1_.ID
where
vet0_.LAST_NAME='y'

The problem is caused by <properties> element which is put to define a unique constraint on firstName and lastName properties together. Unfortunately, this grouping element causing hibernate not to realize that lastName attribute is defined in Person when it is accessed from its subclass within the query.

When <properties> element is removed, HQL works as expected. This is probably a bug in xml based mapping.

Posted in hibernate, java | Leave a comment

Error while generating JAXB Classes from XSD File

You may get following error when you try to generate JAXB classes from your XSD files within eclipse.

 Error: Could not find or load main
class com.sun.tools.internal.xjc.XJCFacade
 

The reason for this error is that you have configured eclipse to use JRE instead of JDK. If you add a JDK through Window>Preferences>Java>Installed JREs, and select it as the active JRE, you will probably get rid of this error.

PS. In some situations, which I haven’t fully understand yet, eclipse insists on using other JRE/JDK configuration other than my current selection. If your error persists after adding JDK, try removing other JRE entries from Installed JREs.

Posted in eclipse, java | Leave a comment

Hibernate’de Sınıf İlişkileri 4

Bir önceki bölümde 1:M ilişkileri incelemeye başlamıştık. Sınıflar arası ilişkilerde en detaylı ilişki türü olan 1:M ilişkileri kaldığımız yerden incelemeye devam ediyoruz.

List türündeki 1:M ilişkiler ise performans açısından en problemli olan ilişki türüdür. List duplikasyona izin verir ve elemanların ekleme sıralarını da korur. Dolayısı ile elemanların list içerisindeki sırasının veritabanında bir sütunda tutulması gerekir. Buna “index column” adı verilmektedir. JPA2′de @OrderColumn annotasyonu ile belirtilmektedir. JPA2 öncesi Hibernate’e özel @IndexColumn annotasyonunun kullanılması gerekmekteydi. @OrderColumn ile @IndexColumn annotasyonlarının bir farkı @IndexColumn ile sıranın sıfırdan başka herhangi bir değerden başlaması sağlanabilir. @OrderColumn’da ise sütun değerleri sıfırdan başlamak zorundadır.

List içerisine yapılan ekleme ve çıkarmalar elemanların index column değerini değiştireceği için Hibernate index column değerlerini birkaç UPDATE ile güncelleme yoluna gidebilmektedir. Bu da list tipi ilişkileri eleman sayısının fazla olduğu ve elemanların sıralarının sıkça değiştiği durumlara pek uygun kılmamaktadır.

List tipli ilişkileri @JoinColumn ile eşleştirmeniz en sağlıklı yöntem olacaktır. Hibernate @JoinTable ile tanımlanmış list tipli ilişkileri yönetirken bazı problemlere neden olmaktadır. Eğer @JoinTable kullanmış iseniz ve list içindeki bir elemanı silmiş iseniz, Hibernate garip biçimde listin son elemanını silmeye çalışıyor. Konuyla ilgili olarak daha detaylı bilgi için bu bug‘a bakabilirsiniz.

List tipli 1:M ilişki eğer çift yönlü bir ilişki ise karşımızda dikkat etmemiz gereken bir nokta var demektir. Eğer bu durumda mappedBy attribute’unu @OneToMany annotasyonu üzerinde kullanırsak ilişkiyi diğer taraf yöneteceği için Hibernate List içerisine yapılan ekleme ve çıkarmalarla ilgilenmeyecek, bu durumda da index column değerleri sağlıklı biçimde yönetilmeyecektir. Çift yönlü list tipli ilişkiler mutlaka 1:M tarafı üzerinden yönetilmelidir. Ancak @ManyToOne annotasyonu mappedBy attribute içermez. Yapmamız gereken aynı @JoinColumn annotasyonunu iki tarafta da tanımlamak ancak M:1 tarafını insertable ve updateable attribute’larını “false” yaparak read-only bir ilişki şeklinde tanımlamak olacaktır.

Map kullanılan 1:M ilişkileri ise en nadir karşımıza çıkan ilişkilerdir. Ancak bazı özel senaryolarda oldukça kullanışlı olabilmektedirler. Bilindiği üzere java.util.Map Java Collection API’sine dahildir, ancak bir collection değildir. key-value ikililerini tutar. key değerleri map içerisinde benzersiz olmalıdır. Başka bir ifade ile duplikasyona izin verilmez. Eklenen key-value pair’lerinin ekleme sıraları da korunmaz.

Value değerleri entity olan map tipli 1:M ilişkilerde key değerlerinin ne olacağı @MapKey annotasyonu ile belirtilmelidir. @MapKey annotasyonuna verilen değer hedef entity’nin sınıfındaki bir “property” ismi olmalıdır. En sık düşülen hatalardan birisi buraya sütun ismi yazmaktır. Bu property ayrıca “persistent” bir property olmalıdır. Value değerlerinin bileşen olduğu durumlarda ise @MapKey yerine @MapKeyColumn kullanılmalıdır.

Bir sonraki yazımızda bileşen içeren ilişkileri yakından inceleyeceğiz.

Posted in hibernate, java, jpa | Leave a comment

Tomcat SSL Client Authentication Konfigürasyonu

Herkese merhabalar. Güvenli, kriptolu iletişim amacıyla https bağlantısnı kullanırız. Client tarafı, server tarafının kim olduğunu güvenilir bir sertifika ile bilebilir. Client authentication (istemci kimlik doğrulaması) dediğimiz olay ise client’ın göndereceği sertifika ile kimliğinin doğrulanmasından ibarettir.  Bu yazımızda  tomcat’in client authentication özelliğini devreye almayı göreceğiz.

Öncelikle elimizde client sertifikalarını kendisinden üreteceğimiz bir root sertifika bulunması gerekiyor. Bu sunucu sertifikasını tomcat’in truststore’una koyacağız. HTTPS bağlantı kurulabilmesi için client’ın authenticated olmasını zorunlu tutacağız. Bunun için clienttan bir sertifika göndermesini isteyeceğiz. Clienttan gelen sertifika eğer tomcat truststore’da bulunan sertifikalarca güvenilir bulunursa bağlantı gerçekleşecektir.

SSL ile https bağlantısı konfigürasyonu yapmamız gerekiyor. Bunun için bir keystore ve truststore gerekli. Java keytool aracını kullanarak bunları üretebiliriz:

keytool -genkeypair -alias tomcat -keyalg RSA -keystore keystore.jks

Komutunu kullanarak keystore üretebiliriz.

Sunucu sertifikasını import ettiğimiz bir truststore üreten komut:

keytool -import  -file server_certificate.cer -keystore truststore.jks

Tomcat konfigürasyon dosyalarından server.xml dosyasında https bağlantısı tanımını eklemeliyiz.
clientAuth=”true” parametresi, bağlantı kurulabilmesi için client’ın geçerli bir sertifika göndermesini zorunlu kılmaktadır. “want” değerini verir isek, sunucu yine sertifika isteyecektir fakat geçerli bir sertifika gelmemesi halinde de bağlantı gerçekleşecektir. Public içerik sunmak istediğimiz durumlarda kullanılabilir. “false” değeri verilmesi durumunda herhangi bir kimlik sorgulaması yapılmayacaktır.

<Connector SSLEnabled="true" clientAuth="true"
disableUploadTimeout="true" maxThreads="150"
port="8443" keyAlias="tomcat" keystoreFile="/path/to/keystore.jks" keystorePass="password"
truststoreFile="/path/to/truststore.jks"
protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https"
secure="true" sslProtocol="TLS" />

Sunucu tarafında yapılacak konfigürasyonu tamamladık. Client sertifikası yüklü olan bir browserdan yapılacak isteklerle konfigürasyonumuzu test edebiliriz.

Posted in java, tomcat | Tagged , | Leave a comment

To Be Or Not To Be, That Is The Question

William Shakespeare’in ölümsüz eseri Hamlet, yıllar boyunca oyuncularını belki kolayca hatırlayamayacağımız bir çok filme ya da tiyatro oyununa konu olmuş, adlarını çoktan unuttuğumuz farklı yayın evleri tarafından defalarca basımı yapılmış fevkalade bir eserdir. Nedir Hamlet’i bu denli farklı ve ölümsüz yapan? Elbette ki oldukça ustalıkla kurgulanmış senaryosu.

Hamlet’ten bir alıntıyı “Yazılım Projelerinde Gereksinim Analizi” adlı yazı dizimizin devamı niteliğinde olan bu yazımızın başlığı olarak kullanmamın bir sebebi var. Yazılım projeleri de tıpkı bir tiyatro oyunu gibi kurgulanır, tasarlanır ve sahneye konur. Bu sürecin belki de en önemli safhası, senaryoları gerektiği titizlikte hazırlamaktır. Senaryolar, hali hazırda (as is) var olan işleyişi analiz etmekte olduğu kadar ortaya konacak (to be) olan çözüm için de büyük öneme sahiptir. Bu nedenle senaryolar üzerinde mutabık kalmak geliştirilecek olan ürün için harcanan efor ve zamanın boşa gitmemesi için oldukça önemlidir.

Senaryoları belirlerken yapılan en büyük yanlışlardan biri, ortaya konacak olan çözüme yoğunlaşmaktır. Bu durum, analistin mevcut işleyişteki ince noktaları gözden kaçırmasına sabep olabilir. Özellikle konuşkan paydaşlarla yapılan analiz çalışmalarında zamanın boşa geçtiği ve ilerleme kaydedilemediği algısı analisti sonuç odaklı düşünmeye itebilir. Bunun sonucunda da analist, söyleşiyi farklı noktalara yönlendirebilir. Bu anlar oldukça riskli dönüm noktalarıdır. Çünkü o an için önemsiz ve kapsam dışı olarak görülen bir detay ilerleyen safhalarda hayati öneme sahip bir konunun temeli olabilir.

Bu tür durumlarda yapılması gereken, soğukkanlı davranmak ve sınırları net bir biçimde belirlemektir. Bunun için de yapılması gereken, eğer konunun farklı noktalara gittiği şeklinde bir algı oluşmuş ise, projenin başlangıcında ortaya koyduğumuz amaç ve kazanımları yeniden gündeme getirmek konuşulanların bu kazanımlara olan etkisini masaya  yatırmak olmalıdır.

Çoğu zaman geliştirilecek olan uygulamanın sunacağı kabiliyetlere odaklanmak, business açısından önemli olan adımları gözden kaçırmaya yol açabilir. Gözden kaçan bu noktalar aslında doğrudan uygulama ile ilgili olmasa da dolaylı olarak uygulamayı etkileyecek adımlar olabilir. Bu aşamalar net bir biçimde belirlenmez ise projenin ilerleyen aşamalarında bu boşluk yersiz ve yanlış varsayımlarla doldurulabilir. Bu da gereksinimleri karşılamaktan uzak bir ürünün ortaya çıkmasına sebep olur.

Bu bağlamda senaryoları business ve product senaryolar olmak üzere ikiye ayırabiliriz. Business senaryolar işleyişi uçtan uca kapsayan tüm hikayedir. Product senaryolar ise hikayenin bütünü içerisinde uygulama tarafından gerçekleştirilecek olan kısımlardır. Önceki yazılarımızda da değindiğimiz su sipariş sistemi üzerinden örnek verecek olursak; müşterinin telefon açması ile başlayan ve suyu alıp ödemeyi yapması ile sonlanan sürecin tümü bir business senaryodur. Bu senaryo müşterinin çağrı merkezini araması ile başlar, çağrı merkezi müşterinin siparişini, teslimat ve ödeme bilgilerini alır ve dağıtıcıya iletir, dağıtıcı siparişi teslim eder ve ödemeyi tahsil eder. Kabaca tanımladığımız bu işleyiş detaylandırıldıkça bazı adımların geliştirilecek uygulama üzerinden yürüyeceği, bazı adımların ise manuel işletileceği ortaya çıkacaktır. Product senaryolarını açık ve net bir biçimde belirleyebilmek için öncelikle business senaryolar belirlenmelidir.

Senaryolar üzerinde çalışmaya ilk olarak normal işleyiş (happy path) üzerinden başlamak gereklidir. Özellikle teknik kişilerin bulunduğu çalışmalarda, belki de entellektüel seviyenin korunmaya çalışılmasından dolayı, konunun akışı normal işleyişten çok aykırı ve özel durumlara yönlenebilir. Bu gidişat bir süre sonra insanların kendilerini ana fikirden uzaklaşmış ve problemlere work around çözümler arar hale gelmiş bir yerlerde gezinirken bulmalarına sebep olabilir. Bu nedenle normal durum senaryolarını tam olarak bitirmeden aykırı ve özel durumlara geçilmemelidir.

Normal durum senaryoları tamamlandıktan sonra alternatif işleyişler üzerine düşünülmelidir. Alternatif akışlar normal işleyişe paralel olarak yürütülebilen ve sonunda aynı sonuca ulaştıran farklı yollardır. Örneğin müşterinin ödemeyi nakit yapması beklenirken promosyon kuponu kullanması gibi.

Alternatif adımlar da belirlendikten sonra aykırı durumlar ve what-if senaryoları üzerinde konuşulmalıdır. Aykırı durumlar, normal işleyişi kesintiye uğratan adımlardır. Örneğin “Dağıtıcı müşterinin adresine gittiğinde adreste kimse yoksa ne yapmalı?” sorusunun cevabı bir aykırı durum senaryosudur.

Aykırı durum senaryoları da net bir biçimde ortaya konduktan sonra negatif senaryolar üzerinde çalışılmalıdır. Negatif senaryolar, normal akışta adımların art niyetle ya da bilmeyerek! farklı bir biçimde işletilmesi durumudur. Örneğin müşterinin aslında olmayan bir adres vermesi durumunun ele alınması.

Senaryolar üzerinde yukarıda belirttiğimiz detaylarda çalışıldıkça işleyiş evrilecek ve tıpkı bir heykeltraşın eseri gibi zamanla mükemmelleşecektir. Böylece business ve product senaryolar arasındaki ayrım ve sınırlar da daha da belirgin bir hale gelecektir. Bundan sonraki adım, senaryoların detayların gözden kaçırılmasını önleyecek bir biçimde ifade edilmesidir. Bunun için use-case çizenekleri, metinsel bir şablon ya da aktivite diyagramları kullanılabilir. Bunlardan hangisini kullanmak daha iyidir gibi bir tartışmaya girmeyi oldukça gereksiz bulduğumu özellikle belirtmek isterim. Neticede bunların her biri bizim alet çantamız içindeki araçlarımızdır. Uygun olanını kullanmak da tamamen bize kalmış.

Posted in genel, java, project management | Tagged , , , , , | Leave a comment

Nasıl Profesyonel Olunur ? – 2

Herkese merhabalar!

Profesyonel yazılımcı olma yolunda tavsiyeleri konu edindiğimiz yazı dizimize devam ediyoruz. Birinci bölüme buradan ulaşabilirsiniz.

8 – Kalite Kontrole Hata Bırakmayın

Kalite kontrolcüyü testçi olarak kullanmayın. QA aşamasına gelen kodda onlarca bug bulunmamalı. Tek tük gözden kaçanlar olabilir fakat koca bir liste dolusu bug, birşeylerin ters gittiğine işarettir.

9 – Birbirinizin Yerini Doldurabilir Olun

Yazılım işi takım oyunudur. Takımdan biri eksildiğinde oyun durmamalıdır. Diğer elemanlar eksiğin yerini mümkün olduğunca doldurabilmelidir. Bu nedenle takım arkadaşlarınızın ne iş yaptığından haberdar olun. Kodlarına göz atın. Hatta belli aralıklarla beraber çalışın. Pair programming bir yöntem olarak kullanılabilir. Amacımız, takımdan biri herhangi bir nedenle eksildiğinde işin kaldığı yerden devam ettirilebilmesidir.

10 – Dürüst Tahminler Yapın

İşin ne kadar zaman alacağı tahminlerini yapmak kolay değildir. Bu nedenle “3 hafta” gibi kesin ifadeler yerine değişik ihtimaller ve bu ihtimallerin olasılık yüzdesi bilgisinin verilmesi daha uygundur. Mesela, “İyi ihtimalle 2 veya 3 hafta sürebilir. Düşük bir ihtimalle 1 haftada bitirme durumumuz  da var.” gibi bir ifade kullanılabilir. Zaman içerisinde gelişen olaylara göre de tahmininizi güncelleyebilirsiniz.

11 – “Hayır” Demesini Öğrenin

Profesyonelliğin getirdiği sorumluluklardan biri de “hayır” diyebilmektir. İnandığınız sürece “evet” demek tabii ki iyidir, fakat yeri geldiğinde “hayır” diyebilecek tek kişi olduğunuzu unutmayın.

12 – Tekrar Eden İşleri Otomatize Edin

İşlemlerin otomatik araçlarla yapılması. Programcıları muhatap alan bir yazıda bundan bahsedilmesi absürd kaçabilir belki ama hatırlatmakta fayda var. Projeyi build etme, testleri çalıştırma, vs. gibi tekrarlanan işler için araçlarımız dururken bunları bir adam pahasına yapmayın.

13 – Kendinizi Sürekli Geliştirin

Bir doktor veya avukat nasıl mesleki yaşamı boyunca öğrenmeye devam ediyorsa bir yazılımcı da öyle olmalıdır. Hergün yeni bir dil, framework, kütüphane ortaya çıkıyor. Bunların her birine en azından dokunmuş olun. Yeni bir teknik geliştiğinde bunun farkında olun. Bu arada bu işleri mesai saatleri dışında yapmanız gerektiğini unutmayın.

14 – Ekibinize Yeni Katılanlara Yol Gösterin

Yeni gelen arkadaşlarınıza deneyimlerinizi aktarın. İşlerin nasıl yürüdüğünü anlatın, pair programming yapın. Böylece sizin yapmış olduğunuz hataları tekrarlamayacaklarından emin olun.

Yazılım uzmanı olma gibi bir emeliniz varsa bu tavsiyeleri göz önünde bulundurmanızı öneririm. Ciddi manada benzerlerinizden sıyrılmanızı sağlayabilirler. Gelecek paylaşımda buluşmak üzere…

Posted in genel, java, project management | Leave a comment

Gereksinim Toplama Yöntemleri

“Yazılım Projelerinde Gereksinim Analizi” adlı yazı dizimize devam ettiğimiz bu yazımızda gereksinimleri toplarken kullandığımız yöntemler üzerinde duracağız. Gereksinim toplama konusunda çeşitli makale ve kitaplarda bu kavramın İngilizce’de “analysis“, “collecting“, “gathering” ya da “trawling” gibi kelimelerle ifade edilmeye çalışıldığını görüyoruz. Gereksinim toplama kavramı aslında bu ifadelerin tümünü kapsayan bütünleşik bir süreçtir. İş süreçlerinin çözümlenmesi, beklentilerin toplanması, ihtiyaçların derlenmesi bu sürecin birer parçasıdır. Amaç, kişilerin beyin kıvrımlarında gizlenen gereksinimlerin gün yüzüne çıkarılmasıdır. Bu yazımızda bunun için kullanılan yöntemlere kısaca değinmeye çalışacağız.

Gereksinm toplama konusunda en pratik olan ve bu yüzden belki de en çok edilen yöntem yüz yüze yapılan görüşmelerdir. Bu yöntemde paydaşlar ile mülakatlar yapılır ve bu mülakatlarda gereksinimler üzerine konuşulur. Genellikle soru-cevap şeklinde devam eden bir süreçtir. Çalışmanın verimliliği açısından sorulacak sorular oldukça önemlidir. Bu nedenle mülakat öncesinde mutlaka bir hazırlık yapılmalıdır.

Çoğu zaman gereksinimler üzerinde farklı paydaşların farklı fikirleri olacaktır. Bu tür durumlarda birbirinden bağımsız mülakatlar yapmak yerine fikirlerin açıkça ortaya konup kararların alınabileceği toplantılar düzenlemek daha verimli olacaktır. Toplantıları verimli geçebilmesi için öncesinde mutlaka toplantı gündemi katılımcılara bildirilmeli, kısaca yapılacak çalışmanın niteliği hakkında ön bilgilendirme yapılmalıdır. Toplantı konusu ile ilgili olarak karar verici mercilerin toplantıya katılımı mutlaka sağlanmalıdır. Toplantı süresince toplantı gündemi dışına çıkılmaması için azami gayret gösterilmelidir. Toplantı sonrasında ortaya çıkan aksiyon, karar ve varsayımlar açıkça belirtilmelidir.

İş süreçlerini analiz etmenin en sağlıklı yolu, mevcut süreci gözlemlemek ve hatta bu süreçte rol almaktır. “Çıraklık” olarak tabir edebilecğimiz bu yöntemde analist, tıpkı ustasını izleyen bir çırak gibi yapılan işi gözlemler. Sorumlu personelin gözetiminde işleyişe bizzat dahil olur. Böylece mevcut işleyişi birinci elden örenmiş olur. Bu yöntem, kelimelerle ifade edilenden daha fazlasını görme imkanı verdiği için oldukça yararlıdır.

İnsanların doğal ortamlarında çok daha rahat oluşu, yardım severlik, önemsenme güdüsü ya da ben bilirimcilik duygularıyla girişecekleri öğretme çabası gereksinimleri toplamak için bulunmaz nimetlerdir. Öte yandan çıraklık zaman alan bir süreçtir. Bu nedenle hangi konularda bu yönteme başvurulacağına dikkatli karar vermek gereklidir. Örneğin önceki yazılarımızda üzerinde durduğumuz su dağıtım otomasyonu için çağrı merkezi kullanıcıları ile böyle bir çalışma yapmak büyük yarar sağlarken, cep telefonuna gelen sms’e göre dağıtım yapan personelin yanında çıraklık yapmanın herhangi bir getirisi olmayacaktır.

Mevcut süreci gözlemlemek her zaman doğru gereksinimleri elde etmeye imkan vermeyebilir. İnsanlar sürekli aynı işi aynı şekilde yapmaya başladıklarında yeni yöntemlere karşı istemsiz bir körlük oluşur. Herhangi bir sorun çıkmadığı müddetçe iş süreçleri üzerinde pek kafa yormazlar. İyi, mükemmelin en büyük düşmanıdır. Bu nedenle gereksinimleri ortaya çıkarabilmek için temel konularda çalıştaylar düzenlemenin büyük faydası vardır. Bu çalıştaylarda konunun uzmanı  kişilerle birlikte mevcut süreçler masaya yatırılır. Süreçteki kırılgan noktalar ve dar boğazlar tespit edilir. Çözüm ve iyileştirme önerileri tartışılır. Çalıştaylar, geliştirilen ürünün getireceği marjinal fayda açısından oldukça önemlidir.

Akıl akıldan üstündür. Bu nedenle gereksinimlere farklı bakış açılarıyla yaklaşmak, problemin ve dolayısıyla çözümün farklı yönlerini görebilmek için uygulanabilecek yöntemlerden biri de beyin fırtınası seanslarıdır. Bu seanslarda kişiler adeta sesli düşünerek fikirlerini ortaya koyarlar. Böylece farklı bakış açıları geliştirilmiş olur. Beyin fırtınaları, özellikle ketum paydaşların konuya dahil olabilmesini sağlamak açısından oldukça faydalıdır.

Başta beyin fırtınası seansları olmak üzere toplantılarda simültane bir içimde konudan konuya atlanılabilir, bir konu tam anlamıyla netlik kazanmadan onunla ilintili farklı bir konuya geçilebilir. Çünkü insan zihni, kavramları birbirleriyle olan ilişkileri ile bütünleşik bir şekilde tanır. Bu tür durumlarda konu bütünlüğünü sağlamak için mind map‘ler kullanmak yararlı olabilir. Mind map’ler Ana konu çevresinde kümelenmiş alt başlıkları ve kavramları birbirleri ile ilişki içerisinde tutan ağaç çizenekleridir. Gereksinim analizinde mind map kullanmanın oldukça büyük faydası vardır.

Gereksinimler toplanırken bazı konularda bazı grupların (örneğin müstakbel kullanıcı kitlesinin) görüşlerine ihtiyaç duyulabilir. Bu gruplar onlarca ya da yüzlerce kişiden oluşabilir. Bu kişilerin tümünü bir araya getirmek çok olası değildir. Bu tür durumlarda önceden hazırlanmış formlar ve anketlerden yararlanılabilir.

Hali hazırda kullanılmakta olan bir uygulamanın ikamesi için yapılan çalışmalarda mevcut uygulama incelenerek ve sunduğu yetenekler tespit edilerek gereksinimler hakkında fikir sahibi olunabilir. Bu yönteme reverse engineering adı verilir. Reverse engineering, gereksinim analizi için tek başına yeterli olmasa da faydalı olacağı aşikardır.

Bir başka faydalı çalışma da konuyla ilgili literatür taraması, araştırma yapılması ve mevcut dokümanların incelenmesidir. Böylece probleme ilişkin bir takım şablonlar ve çözümler tespit edilebilir. Senaryolar genel geçer kalıplara benzetilebilir. Metaforlardan yararlanılabilir. Çeşitli personalar (aktör profilleri) ve prototiplerden yararlanılabilir. Bu çalışmalar problemi ve çözümünü somutlaştıracağı için hem iletişim daha kolay sağlanabilecek, hem de yanlış anlamaların önüne geçilebilecektir.

Gereksinim toplama sürecinde wiki sayfaları, bloglar, forumlar ve hatta koridor duvarlarına asılan A3 kağıtlardan bile faydalanılabilir. Bazen yararlı fikirler insanların aklına en olmadık zamanlarda gelebilir. Bu fikirlerin paylaşımını sağlayacak ortamlara kolay bir erişim sunmak son derece önemlidir.

Gereksinim analizinde güncel teknolojinin sunduğu fotoğraf, video ve ses kayıt cihazlarından da yararlanılabilir. Tabi ki bu tür durumlarda paydaşların da karşılıklı onayını almak nezaket gereğidir. Bazı kişiler video ve ses kaydı mevzu bahis olduğunda tedirgin olup geri çekilebilirler. Bu gibi durumlarda kişilerin tercihlerine saygılı olmak gerekir.

Gereksinim toplamak, çok yönlü beceri ve büyük sabır isteyen bir süreçtir. Bu nedenledir ki analysis, collecting, gathering, trawling gibi farklı kelimelerle ifade edilir. Bu süreçte en önemli rolü üstlenen analist, aynı zamanda sürecin verimli bir şekilde ilerlemesini sağlamakla görevli bir katalisttir. Analistin görevini en iyi şekilde yapabilmesi için kullanabileceği yöntemleri sıralamaya çalıştık. Unutulmamalıdır ki her bir proje bir diğerinden farklıdır. Kullanılacak yöntemlerin seçiminde bu durumu göz önünde bulundurmak da oldukça önemlidir.

Posted in genel, java, project management | Tagged , , , , , , | Leave a comment

Nasıl Profesyonel Yazılımcı Olunur?

Herkese merhabalar. Bu yazımızda Robert C. Martin‘in, nam-ı diğer Bob Amca’nın, profesyonellik adına biz yazılımcılara sunduğu altın öğütlerden bahsedeceğiz.

cleancode

Kısaca profesyonellikten bahsedelim. İşini ciddiye alan, yaptığı iş ile gurur duyan, neye ihtiyacı olduğunu bilen ve bu ihtiyaçlardan taviz vermeyenler profesyonel olarak nitelenirler. Yazılım dünyasında da durum böyledir. Bu vasıfları taşıyanlara profesyonel, usta veya ilkeli yazılımcı denir.

Etrafımıza baktığımızda içinde yazılım bulunan cihazların günden güne arttığını görmekteyiz. Böyle bir ortamda ilkesiz olarak yazılım geliştirmek ciddi maddi zararlara neden olabileceği gibi can kayıpları ile sonuçlanan felaketlerle de karşılaşılabilir.

Peki nasıl profesyonel yazılımcı olunur? Takip edilmesi gereken ilkeler nelerdir?

1 – Çöp kod teslim etme! – We will not ship shit!

Hangi koşullar altında olursa olsun. Patronunuz ne kadar ısrarcı olursa olsun, çöp kod teslimi yapmamalısınız. Kodun kötü durumda olduğunu, tamamlanabilmesi için biraz daha zaman gerektiğini söyleyecek tek kişi sizsiniz.

2 – Daima hazır ol!

Her an projenin deploy edilebilir ve çalıştırılabilir durumda olduğundan emin ol.  Sürüm hazır değil, kalite kontrolde bekliyor vb. gecikmelere veda etme zamanı. Sürüm yayınlandıktan sonra kararlı duruma getirmeye çalışma. Her zaman kararlı bir sürümün bulunsun. Derlenmeyen veya çalışmayan kodun repositorde yeri yoktur.

3 – İstikrarını koru! – Stable Productivity

Üretkenliğin, uğraştığın kodun azlığıyla veya fazlalığıyla değişmemeli. Yeni bir özelliği implement etme hızın belli bir sabitin altına inmemeli. Bunu yapabilmen için de kodu keşmekeş içine sokmadan sürekli olarak temiz tutmak durumundasın.

4 – Esneklik – Inexpensive Adaptability

Sisteme yeni bir özellik eklemek veya çıkarmak, sistemin baştan sona tekrardan tasarlanmasını gerektirmemeli. Müşterinin fikir değiştirme olasılığı oldukça yüksek olduğundan sistem en baştan modüler bir yapıda tasarlanmalıdır. Kullanılan veritabanı birkaç gün içerisinde değiştirilebilir olmalı. Hatta ilişkisel veri tabanından NoSQL veritabanına geçiş ihtimali bile düşünülmelidir.
Web sadece bir I/O bileşenidir. Web olmadığı zamanlarda da uygulamalar olduğu gibi gelecekte de webin değişeceği öngörülebilir. Uygulama herhangi bir i/o channela uyarlanabilir şekilde tasarlanmalıdır.

5 – Gelişimi Sürekli Kıl – Continuous Improvement

Yeni bir kütüphane veya dil çıktığında mümkün olduğunca kullanmaya bak.  Kodu bulduğundan daha temiz bırak.

6 – Koda Dokunmaktan Korkma – Fearless Competence

Kodda değişiklik yapmaktan korkma. Hatalı gördüğün yeri düzelt. Bozmadığından emin olmak için değişik disiplinlerden faydalanabilirsin, Test Driven Development gibi.

7 – Yüksek Kaliteyi Hedefle – Extreme Quality

Yapabileceğinin en iyisini yap. Yazabileceğin en temiz kodu yaz, yapabileceğin en dürüst tahminlerde bulunun,  tasarlayabileceğin en esnek, uyarlanabilir mimariyi tasarla.

Bob Amca’nın öğütleri önümüzdeki yazılarda devam edecek. Bir sonraki paylaşımda buluşmak üzere…

Posted in agile, java, project management | Leave a comment

Yazılım Performansı Terminolojisi

Performans denilince aklımıza gelen sadece “hız” mıdır? A programı B programından hızlıysa her zaman A mı tercih edilmelidir? Bu yazımızda bu sorulara cevaplandırmada yardımcı olması amacıyla yazılım performansını ölçerken kullandığımız anahtar kelimelerden bahsedeceğiz.

Performance

Response Time : (tepki süresi) Sistemin dışarıdan aldığı bir isteği işleyip cevap verene kadar geçen süreye denir. Örnek olarak “topla” tuşuna basmanız ile hesap makinesinin girilen değerleri toplayıp ekranda göstermesi arasında geçen süre verilebilir.

Responsiveness: (duyarlılık) Sistemin bir kullanıcı isteğine ne kadar çabuk tepki verdiği ile alakalıdır. Kullanıcı memnuniyeti açısından önemlidir çünkü kullanıcı isteğinin alındığını ve işleme başlandığını bilmek ister. Tuşa bastıktan sonra ekranda bir değişiklik görmeyen kullanıcı hayal kırıklığına uğrayabilir. Kullanıcı “Rapor üret” tuşuna bastığında ekranda gösterilecek bir ilerleme çubuğu response time‘ı yani rapor üretme süresini değiştirmese de responsiveness‘ı arttıracaktır.

Latency:(gecikme süresi) Sistemin gelen çağrıya hiçbir iş yapmadan anında cevap verse bile cevabın bize ulaşmasına kadar geçen minimum süredir. Önümüzdeki bilgisayarda bu süre sıfıra yakındır fakat uzak sistemlerde isteğin karşı tarafa gidip hiçbir işle oyalanmadan tekrar geri gelmesi bile saniyeler alabilir. Bu nedenle uzak sistemlere yapılan çağrıların en aza indirilmesi önerilir.

Throughput: (iş/zaman) Birim zamanda yapılan iş miktarı. Kurumsal uygulamalarda saniyede yapılan transaction sayısıyla ölçülmektedir (transactions per second tps).

Yazılım performansından bahsederken ya response time’dan ya da throughtput’tan bahsedilmektedir. Kullanıcı bakış açısıyla bakıldığında ise responsiveness daha önemli olabilmektedir. Bu nedenle daha kötü response time veya throughput pahasına da olsa responsiveness’ı arttırmak, yazılımınızın performansını arttırabilir.

Load: (yük) Bir sistemin ne kadar yük altında olduğunu anlatmak için kullanılır. Sisteme o anda bağlı olan kullanıcı sayısı ile ölçülebilir. Load genelde diğer ölçülerle, mesela response time ile beraber kullanılmaktadır. Örneğin “Sistem 100 kullanıcılı iken response time 0.5 saniye, 200 kullanıcılı iken 2 saniyedir.” denilebilir.

Efficiency: (verimlilik) Kısaca birim kaynakla üretilen performans (performans / kaynak) şeklinde tarif edebiliriz.  2 işlemci ile 30 tps performans elde edilen bir sistem, 4 işlemci ile 40 tps performans elde edilen sistemden daha verimlidir denilebilir.

Capacity: (kapasite) Sistemin istenilen şekilde çalışmaya devam edebildiği maksimum load veya throughput’a denir.

Scalability:(ölçeklenebilirlik) Sisteme eklenen ek kaynakların performansı nasıl etkilediğinin ölçüsüdür. Eklediğiniz donanımla orantılı olarak performans artışı sağlayan sistemler ölçeklenebilir (scalable) sistemlerdir. Tek bir sunucunun gücünü arttırmaya vertical scalability, sisteme birden fazla sunucu eklemeye ise horizontal scalability denir.

Kurumsal uygulamalar tasarlarken kapasiteden hatta verimlilikten daha çok ölçeklenebilirliğe dikkat edilmesi tavsiye edilmektedir. Performansa ihtiyaç duyduğunuzda scalability ile istediğinizi daha ucuza elde edebilirsiniz. Scalable bir sistemde çoğu kez yeni donanım almak, yeni yazılımcı almak veya yazılımı upgrade etmekten daha ucuza gelmektedir.

Bu yazımızda yazılım performansı denince akla gelen terimlere aşina olmaya çalıştık. Bir sonraki paylaşımda buluşmak üzere…

Posted in genel, project management | Tagged , | Leave a comment

How to Switch from One DB Instance to Another at Runtime

Sometimes we may need to switch from one db instance from another during runtime. Actually this is very easy if you are using Spring and DataSource API in order to obtain DB connections. Lets look at our solution for such a requirement.

switch_db_at_runtime

Our solution lays on “proxy pattern“. Spring provides us with ProxyFactoryBean so that we can easily create a proxy bean which is depended on by others instead of real bean and delegates requests to its “target” bean.

Target bean can be directly given to proxy bean or instead it can be accessed over a TargetSource instance. Here we employ a special implementation of TargetSource called as HotSwappableTargetSource. HotSwappableTargetSource bean allows us to swap real target at runtime via its “swap” method. Initially it is configured with an “initialTarget“, however, later it can be replaced with any other suitable bean by just calling swap method given “newTarget” as the input parameter.

Such a requirement may come up with in your project as well. You may want your application to use temporarily another DB instance during maintenance for example. In such cases you will also need to handle other cases such as invalidating currently logged in users’ sessions, object caches etc.

Posted in design patterns, java, spring | Leave a comment