Skip to content

Scala Traits

March 16, 2010
tags: ,

In questo articolo vedremo una delle interessanti caratteristiche del linguaggio Scala riguardo i mixin. In Java abbiamo la possibilità di implementare un qualsiasi numero di Interface a piacere, ma purtoppo non è possibile riutilizzarne l’implementazione .     Per riutilizzare queste implementazioni si può utilizzare l’Aspect Oriented Programming utilizzando mixin/introduction. Vediamo questo aspetto implementativo utilizzando Scala.

Scala fornisce la possibilità di definire le astrazioni come nelle Java Interface chiamate Trait, ma in più possiamo anche definire l’implementazione della astrazione dentro il Trait.

Vediamo ora l’utilizzo dei Trait scrivendo del codice usando il pattern Observer.

trait Subject {
    /* definisce la struttura di un observer, possiamo pensarla come una classe anonima java */
    type Observer = { def receiveUpdate(subject: Any) }

    // dichiara la lista di osservatori
    private var observers = List[Observer]()
    // definisce il metodo addObserver per aggiungere osservatori
    def addObserver(observer:Observer) = observers ::= observer
    // definisce il metodo di notifica di un evento a tutti gli osservatori
    def notifyObservers = observers foreach (_.receiveUpdate(this))
}

Definiamo ora un generico Component che realizza un command

class Component(val label: String) {
    def execute() = {
      // Logica del componente
    }
}

Utilizziamo il Trait Subject nella classe ObservableComponent per mostrare come viene utilizzato anche il corpo della astrazione (notifyObservers nel nostro caso).

class ObservableComponent(name: String) extends Component(name) with Subject {
    override def execute() = {
        super.execute()
        notifyObservers
    }
}

Per completare l’esplorazione dei Trait vediamo ora come possiamo “impilare” (stackable) i Trait ed estenderli.

Definiamo ora l’astrazione Command ma questa volta senza dargli nessuna implementazione, in modo che ObservableAction la estenda.

trait Command {
   def execute()
}

Utilizzando la keyword with possiamo creare lo stack dei nostri Trait, l’esecuzione dei Trait avviene in base all’ ordine di dichiarazione con i with,  e questo ci permette di comporre in maniera dichiarativa dei comportamenti.

trait ObservableAction extends Command with Subject {
abstract override def execute() = {
   super.execute()
   notifyObservers
}
}

Per brevità diciamo per ora che i Trait, quando utilizziamo la keyword with vengono chiamati da destra a sinistra, altra cosa importante è che possiamo utilizzarli quando ne abbiamo bisogno.

new Component("Hello") with ObservableAction with ...

Author Massimiliano Dessì

Advertisements
No comments yet

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: