2015-04-18 22 views
7

Sto leggendo online sui problemi trasversali da quando ho implementato Log4j nel mio codice. Alcune persone dicono che usare AspectJ è ok, mentre altri sottolineano che rompono la programmazione funzionale. Quelle miscele sono la soluzione di Scala per le preoccupazioni trasversali.Come gestire il taglio trasversale riguarda il modo Scala

Tuttavia, rabbrividisco quando penso che estenderò un tratto a un oggetto/classe che non è correlato.

ad es. new Database with Logger

Qui Logger non ha nulla a che fare con Database, ma è come eseguire il missaggio per fornire la registrazione. Preferirei farlo alla Scala, quindi voglio scoprire che questo è ciò che la gente intende per mixin.

Qualcuno può, per favore, mostrarmi un rapido esempio di come fare questo in Scala?

risposta

5

Questo è un grande argomento con molte potenziali risposte "corrette". Il mio preferito sarebbe utilizzare "per parametri di nome" o funzioni di ordine superiore.

A un esempio molto semplice di questo:

object Logging { 
    def logCall[T](name: String)(block: => T): T = { 
    log.info(s"Invoking: $name") 
    block 
    } 
} 

che permetterebbe di applicare lo sia in un oggetto che si sa circa la preoccupazione trasversale (qualcosa come l'annotazione avvolgendo una chiamata di metodo con qualcosa in java):

class DB { 
    import Logging._ 
    def insert(item: Something) = logCall("insert") { 
    ??? 
    } 
} 

o sul sito chiamata:

import Logging._ 
def businessLogic() { 
    val user = ??? 
    val result = logCall("insert user")(DB.insert(user)) 
    println(result) 
} 

La cosa bella di questo è che è molto esplicito e autoesplicativo (che, ancora una volta, sono le cose che potresti apprezzare o meno).

+1

È come avere una variabile globale in Java. E negherebbe lo scopo dell'iniezione di dipendenza. –

+1

In definitiva, non è la stessa cosa che avere una variabile globale in Java, se si dispone di dipendenze che si desidera siano disponibili nel problema trasversale, è possibile passare tali parametri come normali o impliciti al metodo di taglio incrociato. Non è necessario eseguire il logging per essere un singleton, è stato fatto in questo modo per rendere l'esempio del codice breve (e perché raramente si iniettava un logger). – johanandren

+0

abbastanza giusto. Ho capito il tuo punto ora. –