2017-06-12 72 views
2

我是新的scala編程。我現在很困惑如何以異步和功能的方式聲明一個biz方法,方法實現應該包含許多日誌消息。作爲一個不好的做法,我寫了這樣的代碼:什麼是使用功能方式處理日誌消息的最佳做法

// 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(...) 
    } 
} 

它的壞,導致實現與副作用,登錄INT東西的地方。所以,我改變了方法聲明是這樣的:

// 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(...)) 
    } 
} 

使用作家,副作用被消除,但代碼是不明確的:

  • 爲什麼作家回來了? Writer[Vector[String], Store]Store有更多的噪音,有什麼方法可以避免樣板代碼並保持無副作用?
  • log不是臨時的!我應該使用:+++操作來創建一個字符串矢量來存放消息,以添加日誌。我認爲這不是臨時記錄,就像在任何地方寫log.info(...)一樣。
+0

對我而言,我認爲日誌對我的程序的正確性不重要。所以我選擇不在我的代碼中模擬它們的副作用。我讚揚你對純FP的擁抱,並期待着答案。 – Stephen

+0

是的,也許它可以更純粹 –

回答

1

爲了方便,我認識的大多數Scala開發人員都傾向於將日誌記錄看作「非副作用」。然而,如果你真的想跟蹤他們,你可能想看看「免費monad」的概念。更多信息: general descriptionexample with logging

我的粗略解釋是「讓我們將程序模型化爲一些AST並解釋它」。因此,在AST中,您定義了一個「日誌記錄」的概念,但不是實現,後來才解釋。這種方法可以讓您密切關注日誌記錄,並在不影響代碼的「業務」部分的情況下更改操作(從寫入到/ dev/null到異步發佈到外部服務)。

+0

非常感謝! 「讓我們將我們的程序建模爲一些AST並解釋它」。 太好了!也許我應該爲名爲'log'的配置添加一個屬性。如果使用純粹的fp,「Free」monad是最好的選擇。 –

相關問題