2017-06-12 2 views
2

Ich bin neu in der Scala-Programmierung. Ich bin jetzt verwirrt, wie man eine Biz-Methode asynchron und funktional deklariert, dass die Methodenimplementierung viele Protokollnachrichten enthalten sollte. Als schlechte Praxis, schreibe ich den Code wie folgt aus:Was ist die beste Praxis für die Handhabung Log-Nachricht mit funktionalen Weg

// trait 
trait StoreService { 
    def create[Config]: Kleisli[Future, Config, Store] 
} 

// and the interpreter 
trait StoreServiceInterpreter extends StoreService { 
    def create[Config]: Kleisli[Future, Config, Store] = Kleisli {cfg => 
     // some implementation ... 
     log.info("bla bla bla ...") 
     // some implementation ... 
     // return a store 
     Store(...) 
    } 
} 

Es ist schlimm, bewirken, dass die Umsetzung mit Nebeneffekt ist, melden Sie sich etwas int den Ort. Also, ich die Methode Erklärung wie folgt ändern:

// trait 
trait StoreService { 
    def create[Config]: Kleisli[Future, Config, Writer[Vector[String], Store]] 
} 

// and the interpreter 
trait StoreServiceInterpreter extends StoreService { 
    def create[Config]: Kleisli[Future, Config, Writer[Vector[String], Store]] = Kleisli {cfg => 
     // some implementation ... 
     // log.info("bla bla bla ...") 
     // some implementation ... 
     // return a store 
     Writer(Vector("bla bla bla...", Store(...)) 
    } 
} 

die Writer, der Nebeneffekt eliminiert wird, aber der Code ist nicht klar:

  • Warum ein Schriftsteller zurückgekehrt? Writer[Vector[String], Store] hat mehr Geräusche als Store, hat irgendeinen Weg, den Boilerplate-Code zu vermeiden und den No-Side-Effekt zu bleiben?
  • Schreiben Sie log ist nicht ad-hoc! Ich sollte einen Vektor von String erstellen, um die Nachricht zu speichern, indem Sie :+ oder ++ Operation verwenden, um Protokoll hinzuzufügen. Ich denke, es ist keine Ad-hoc-Protokollierung, genau wie log.info(...) schreiben überall.
+0

Für mich betrachte ich Logs nicht als Material für die Richtigkeit meines Programms. Daher entscheide ich mich, ihre Nebenwirkungen nicht in meinem Code zu modellieren. Ich begrüße Ihre Umarmung von reinen FP und freue mich auf die Antwort. – Stephen

+0

Ja, vielleicht kann es reiner sein –

Antwort

1

meisten Scala-Entwickler Ich weiß, sind in der Regel die Protokollierung als „Nicht-Nebenwirkung“ zu betrachten, für die Bequemlichkeit. Wenn Sie sie jedoch wirklich verfolgen möchten, sollten Sie sich das Konzept "free monad" ansehen. Weitere Informationen: general description, example with logging.

Meine grobe Erklärung ist "Lassen Sie uns unser Programm als einige AST modellieren und interpretieren". In AST definieren Sie also ein Konzept des "Logging", aber nicht der Implementierung, die später in der Interpretation kommt. Auf diese Weise können Sie die Protokollierung überwachen und die Aktion ändern (vom Schreiben in/dev/null in den asynchronen Post zu einem externen Dienst), ohne den "geschäftlichen" Teil des Codes zu beeinträchtigen.

+0

Vielen Dank! > "Lassen Sie uns unser Programm als einige AST modellieren und interpretieren". So gut! vielleicht sollte ich eine Eigenschaft für die Config namens 'log' hinzufügen. Und die 'Free'-Monade ist die beste Wahl, wenn mit Pure-Fp. –

Verwandte Themen