Scala’da case classes, pattern eşleştirme ve exception handling

Evet arkadaşlar selamlar,

Bu blogda arada sırada Scala yazmaya çalışıyorum. Bu ay da Scala’nın bazı özelliklerinden kısaca bahsedeyim istedim. Bu yazıda case classes, kısaca pattern matching ve exception mantığından bahsedeceğim sizlere.

Case classes, normal class mantığından bir kaç sentaktik şeker vererek ayrılan bir olgu. Case class kullandığınız zaman constructorda verdiğiniz parametreler için otomatik olarak içerde private alanlar oluşturuluyor ve bu alanlara yine constructorda verdiğiniz parametre isimlerinden erişebiliyorsunuz. Bu sayede basit POJO lar oluşturmak oldukça kolay hale geliyor. Basit bir örnek vermek gerekirse:

case class Person(firstName: String, lastName: String)

val me = Person("Erkan", "Ahmet")
val first = me.firstName
val last = me.lastName

if (me == Person(first, last)) {
  println("Found myself!")
  println(me)
}

Gördüğünüz gibi bütün sınıf tek bir satırdan oluşmakta. Gerçi bu kavramın adındaki Case nedir diye düşünenleriniz vardır, az bekleyin.

Gelelim pattern matching’e. Java da bu mantık switch case ler üzerinden yürüyor bildiğiniz gibi. Yalnız bu yapı sadece primitif tipleri kontrol edebiliyor. Bu da sizi eninde sonunda bir integer a yada bir enum değerine kadar indirebiliyor. O kadar karmaşık sınıflar yazıyor ama karşılaştıramıyoruz.

Bu soruna Scala’da amcalar neşter atmışlar. Temelde Java’dan ayrıldığı bir kaç noktayı aktaralım:

  1. Case statementları birbiri içine girmezler, yani gidip de hepsine break yazmak zorunda değilsiniz.
  2. Case statementları bir değer dönerler, bunu olduğu gibi kullanabilirsiniz, bu sayede daha az satır kod yazmış olursunuz.
  3. Case statementlar, patternleri eşleştirebilirler, bunun en güzel örneği ise case class kullanımında görülür.

object Scenario{
def apply(user: String, action: GameElement) = {
action match {
case workout: Workout => new WorkoutScenario( workout, user )
case like: Like => new SocialScenario( like, user )
}
}
 }

 

 
Örnekte gördüğünüz üzere, action nesnesi match blokuna sokuldu. Match blokunda, bu action sınıfından türemiş diğer sınıflarla karşılaştırıldı. Bunlar Workout ve Like. Bunlardan hangisi ile eşleştiyse de, buna uygun bir nesne üretildi ve geri dönüldü. İşte ben buna factory pattern derim. Hatta demem, çünkü ortada pattern denecek kadar bir kod parçası yok. : )

Peki gelelim exception handlinge. Scala bu işe de el atmış durumda. Normalde bir noktadan exception throw ederdiniz. Burada sorun yok. Fakat yakalayacağınız yerde, her bir exception tipi için ayrı ayrı blok açar ve ne yapacağınızı şaşırdınız. Scala ise exception handling’de de pattern matching kullanarak, işimizi bir adım daha kolaylaştırıyor.

Örnek vermek gerekirse

</pre>
<address>try{

workoutItems.foreach(item => {
...
if (repeat <= set.repeat_number.toInt) {</address><address>              ....
throw BadgeWon("pushup badge won!")
}

})
}
})

}
catch {
case e:BadgeWon => println("found the badge: " + e.message)
case e => {
println("general exception" + e.getMessage )
e.printStackTrace()
}
}</address><address>
Gördüğünüz gibi çok daha kısa bir kod parçası ile, exceptionlarınızı da yönetmeyi başardınız. Scala kullandıkça özelliklerini daha da çok seveceksiniz.
Önümüzdeki yazıda function literals konusuna değinmek istiyorum, herkese iyi günler!

Exception Handler ve rahatlığı

Arkadaşlar merhaba,

Sizlere bu yazıda kısaca Spring MVC frameworkteki Exception Handler annotationından bahsedeceğim. Bu konu özellikle REST arayüz yazan arkadaşların işine gelebilecek bir teknik.

spring

spring

Malum bir REST arayüz yazdığınız zaman esasen bir API yazmış oluyorsunuz. Haliyle API nizin bir çok metodu oluyor. Bu metodların hepsinde exception handle etmek de can sıkıcı bir durum. Bir süre sonra her metodda exception handle ederseniz ortaya ciddi miktarda tekrarlayan kod çıkacaktır.

Bunu önlemek için geliştirilen çözümlerden biri filtreleri kullanarak fırlatılan exceptionların filtre seviyesinde yakalanması ve işlenmesidir. Ama bu çözüm bütün web trafiğiniz üzerinde  çalışacağından, tüm kodunuzun buna uyumlu olmasına özen göstermeniz gerekiyor.

Diğer yandan yine Spring’in önerdiği bir çözüm ise, hata durumlarına karşı çözücüler yazarak kullanıcıyı istenilen hata sayfalarına yönlendirmek. Fakat bu da REST arayüz yazan  arkadaşların işine pek gelmez çünkü bizim dönmek istediğimiz değerler genellikle JSON nesneleri oluyor.

Bu durumda ortaya ExceptionHandler annotation ı çıkıyor. Bu annotation ı kullanmak için ilgili controllerin, yakalayacağı exception tipini vermeniz gerekli. Kullanacağı metodun içerisinden de istediğiniz loglamaları yaparak gerekli hata nesnesini dönebilirsiniz. Bu bir JSON nesnesi de olabilir, istediğiniz her hangi bir model ve view nesnesi de olabilir.

@ExceptionHandler(AddressNotFoundException.class)
   @ResponseStatus(value=HttpStatus.NOT_FOUND)
public ModelAndView handleAddressNotFoundException(AddressNotFoundException exception) {
ModelAndView modelAndView = new ModelAndView(“nocontact”);
modelAndView.addObject(“message”, exception.getMessage());
return modelAndView;
}

Bu örnekte ModelAndView sınıfı kullanılmış ama burada pek ala ResponseBody annotation ile birlikte bir POJO dönülebilirdi. Bu metodun güzelliği olayı inheritance ile birlikte kullanınca ortaya çıkıyor. Sadece tek bir exception handler metoduyla bütün bir REST apinin exception sorununu çözebilirsiniz. Tek yapmanız gereken Exception Handler metodunu, kullanacağınız base bir controllerın içine yerleştirmek ve işte sağlam yapınız artık hazır!!

Exception ve Throwable Ayrımı

Herkese merhaba,

4-5 saattir bir hatayla uğraşıyorum. wsimport marifetiyle bir web service clientı oluşturdum ve endpoint interface ini alarak çalışmaya başladım. Fakat kodu çalıştırdığımda, ne zaman endpoint interfaceini almaya kalksam kod sessiz bir şekilde hata veriyordu. Sadece bir controllerımdaki finally’e yakalanıyor, sonra da başarısız cevap dönüyordu.

Nasıl olur da hiç bir exceptiona yakalanmaz diye düşünürken, Java’da sadece Exception fırlatılmadığını, Throwable da fırlatıldığını hatırladık bir şekilde. Bu durumda Throwable aradık ve sonuca ulaştık, en azından yaşadığımız hatayı bulabildik. Aklıma iyice kazınsın diye de sizlerle paylaşıyorum arkadaşlar, dikkatli olun ;).

java throwable yapısı

java throwable yapısı