Języki

Erudis - your road to knowledge
Scala w akcji. Konwencja JavaBean w wersji Scala.

Znamy najbardziej podstawowe elementy składni Scali, będziemy chcieli teraz utworzyć prostą aplikację, która pobiera z internetu dane w standardzie RSS (ang. Really Simple Syndication) i zapisuje je do pliku CSV (ang. Comma-separated values). W ten sposób zobaczymy jak Scala radzi sobie z typowymi zadaniami programistycznymi: przechowywaniem obiektów, wejściem-wyjściem oraz przede wszystkim przetwarzaniem danych w XML-u.

Rozpoczniemy od utworzenia mini bazy danych, która będzie nam służyła do przechowywania danych pobranych z internetu. Zanim się za to jednak weźmiemy, musimy poznać jeszcze kilka elementów języka Scala.

Konwencja JavaBean w wersji Scala

Pierwszą rzeczą, jakiej będziemy potrzebować, to klasa reprezentująca pojedynczą informację udostępnioną przez RSS. Ponieważ istnieje wiele wersji standardu RSS, to będą nas interesowały tylko podstawowe, zawsze występujące dane: tytuł, adres URL i opis informacji. Ponadto każda informacja będzie zawierała unikalny identyfikator.

W Javie zwyczajowo do przechowywania danych różnych typów używamy klas utworzonych w konwencji JavaBean. Klasa taka zawiera pola prywatne reprezentujące dane oraz metody T getNazwPola() i setNazwaPola(T), pozwalające pobrać wartość i zmodyfikować pole o nazwie nazwaPola typu T. Często takie metody nazywa się getterami i setterami. Ze względu na to, że tego typu klasy bardzo często są używane, to albo sami poznamy tajniki szybkiego pisania na klawiaturze, albo zmusimy środowisko programistyczne go wygenerowania metod get i set na podstawie podanych pól.

W Scali to samo można osiągnąć o wiele prościej. Popatrzmy najpierw na Listing 2.

Listing 2. Samodzielna implementacja wzorca JavaBean w Scali. Potrzebne są nam tylko metody służące do pobierania danych – "gettery"

package pl.erudis.feedseater.model
import java.net.URL
class RSSFeed(id:String, title: String, url:URL, description: String) {
  def getId = id
  def getTitle = title
  def getUrl = url
  def getDescription = description
}

Tym razem tworzymy klasę Scali, nie obiekt. Klasa ma konstruktor pozwalający przekazać do klasy wartości atrybutów RSS. Konstruktor nie jest osobną metoda, jak to najczęściej bywa, zamiast tego odpowiednie parametry są umieszczane wprost w definicji klasy. Jeżeli w konstruktorze mają być wykonane jakieś operacje, to umieszczamy je w ciele klasy zaraz po jej deklaracji. Zmienne zadeklarowane w konstruktorze są automatycznie dostępne w klasie, więc nie ma potrzeby ich kopiowania. W naszym przypadku ograniczyliśmy się tylko do metod get, zwracające wartości pól. Scala pozwala zdefiniować te metody bardzo zwięźle, ale nas to jeszcze nie satysfakcjonuje.

Klasę typu JavaBean można utworzyć jeszcze prościej, korzystając z metadanej (ang. annotation) @BeanProperty. Demonstruje to kod na Listingu 3. W klasie RSSFeedBean metody get i set będą utworzone automatycznie. Szkoda, że Java jeszcze się nie dorobiła takiej metadanej.

Listing 3. Implementacje klasy typu JavaBean w Scali

package pl.erudis.feedseater.model
import java.net.URL
import java.util.UUID
import scala.reflect.BeanProperty
class RSSFeedBean(@BeanProperty var title: String, @BeanProperty var url: URL, 
      @BeanProperty var description: String) {
   private var id: String = UUID.randomUUID.toString
   def getId = id   
   def this() = this(null, null, null)
}

Pole id jest inicjalizowane przy pomocy klasy UUID generującej unikalny łańcuch znaków.

W Scali, jak w każdym przyzwoitym języku obiektowym, klasy mogą mieć więcej niż jeden konstruktor. W Scali reguła jest taka, że główny konstruktor jest definiowany poprzez podanie parametrów w definicji klasy, a pozostałe poprzez definicję metody this. Klasa RSSFeedBean jest wyposażona w taki dodatkowy konstruktor, który pozwala utworzyć obiekt bez podania parametrów: def this() = this(null, null, null).