登录功能还是使用功能? [英] Log in function or function using it?

查看:77
本文介绍了登录功能还是使用功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否是 best (我知道没有灵丹妙药,但是使用一个优于另一个可能会有一些好处)-登录调用函数,或者调用函数它吗?

Is it best (I'm aware of that there's no silver bullet, but there may be some advantage by using one over the other) - to log in the calling function, or the function calling it?

示例:

方法1

module MongoDb =
   let tryGetServer connectionString =
      try
         let server = new MongoClient(connectionString).GetServer()
         server.Ping()
         Some server
      with _ -> None

用法:

match MongoDb.tryGetServer Config.connectionString with
| None ->
    logger.Information "Unable to connect to the database server."
    // ... code ...
| Some srv ->
    logger.Information "Successfully connected to the database server."
    // ... code ...

方法2

module MongoDb =
    let tryGetServer connectionString =
        try
            let server = new MongoClient(connectionString).GetServer()
            server.Ping()
            Some server
        with _ -> None

    let tryGetServerLogable connectionString logger =
        match tryGetServer connectionString with
        | None -> 
            logger.Information "Unable to connect to the database server."
            None
        | Some srv -> 
            logger.Information "Successfully connected to the database server."
            Some srv

用法:

match MongoDb.tryGetServerLogable Config.connectionString logger with
| None ->
    // ... code ...
| Some srv ->
    // ... code ...

推荐答案

方法2 更好.通常,日志记录是一个跨领域关注点,因此最好将它与实现细节分开.最好通过组合"解决交叉切割问题;在OOD中,这可以通过装饰器或拦截器完成.在FP中,有时我们可以从OOD中学习,因为许多

Approach 2 is better. In general, logging is a Cross-Cutting Concern, so it's best decoupled from implementation details. Cross-Cutting Concerns are best addressed via Composition; in OOD, this can be done with Decorators or Interceptors. In FP, we can sometimes learn from OOD, because many of the principles translate from objects to closures.

但是,我宁愿使用像这样的东西:

However, instead of using Approach 2 above verbatim, I'd rather prefer something like this:

module MongoDb =
    let tryGetServer connectionString =
        try
            let server = MongoClient(connectionString).GetServer()
            server.Ping()
            Some server
        with _ -> None

请注意,MongoDb模块不了解日志记录.这遵循单一责任原则,在函数式编程中也很重要.

Notice that the MongoDb module has no knowledge of logging. This follows the Single Responsibility Principle, which is also valuable in Functional Programming.

tryGetServer函数具有以下签名:

string -> MongoServer option

现在,您可以定义一个与MongoDb模块完全脱钩的日志记录功能:

Now you can define a logging function, totally decoupled from the MongoDb module:

module XyzLog =
    type Logger() =
        member this.Information message = ()

    let tryGetServer f (logger : Logger) connectionString  =
        match f connectionString with
        | None ->
            logger.Information "Unable to connect to the database server."
            None
        | Some srv ->
            logger.Information "Successfully connected to the database server."
            Some srv

在这里,您可以想象XyzLog是使用Serilog,Log4Net,NLog,您自己的自定义日志记录框架或类似文件的特定日志记录模块的占位符.

Here, you can imagine that XyzLog is a placeholder for a particular logging module, utilising Serilog, Log4Net, NLog, your own custom logging framework, or similar...

f参数是具有通用签名'a -> 'b option的函数,其中MongoDb.tryGetServer是特化的.

The f argument is a function with the generic signature 'a -> 'b option, of which MongoDb.tryGetServer is a specialization.

这意味着您现在可以像这样定义部分应用的功能:

This means that you can now define a partially applied function like this:

let tgs = XyzLog.tryGetServer MongoDb.tryGetServer (XyzLog.Logger())

函数tgs 具有签名

string -> MongoServer option

因此,任何依赖具有此签名的功能的客户端都可以在不知道其区别的情况下互换使用MongoDb.tryGetServertgs.

So any client that depends on a function with this signature can use MongoDb.tryGetServer or tgs interchangeably, without knowing the difference.

这使您能够改变主意或相互独立重构MongoDb.tryGetServer和日志记录基础结构.

This enables you to change you mind or refactor both MongoDb.tryGetServer and your logging infrastructure independently of each other.

这篇关于登录功能还是使用功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆