Sco*_*rod 2 f# computation-expression
Computation Expressions是面向方面编程的另一种方法吗?
这是F#解决跨领域问题的解决方案吗?
我查看了以下文章,不禁想到AOP(即面向方面编程).
在本文中,作者提供了一个处理日志记录的计算表达式的示例,但是在不模糊业务逻辑主要意图的情况下隔离了代码的实际日志记录方面.
我的想法准确吗?
是的,monad是一种很好的(和惯用的)方法,可以解决跨领域的问题.monad是一个更通用的概念,但它们可以用于模拟系统中的效果之一.
在FP术语中,单词效果通常意味着副作用.诸如日志记录,审计,性能监控,缓存和计量等所有(根据定义)的跨领域问题都有副作用.由于它们涉及将数据"写入"辅助有状态资源,因此可以使用State或Writer monad对其进行建模.
其他跨界问题,如身份验证,授权和验证,通常可以通过Reader monad(或者可能是State monad)来解决.
F#计算表达式提供了对monadic组合器的语法糖(本质上是返回和绑定),与Haskell的do符号相同.但是,与Haskell相反,您必须自己为monad定义计算表达式构建器,除了已经内置到语言(async,seq)中的少数几个.
使用monad来解决交叉问题是一种与AOP不同的方法.
在面向对象的编程中,对AOP有两种根本不同的看法:
正如我在书中解释的那样,我认为编译时编织是解决问题的一种笨拙且不灵活的方式.使用装饰器是实现相同目标的更优雅和灵活的方式.
我对该陈述的动机是我倾向于分离关注点.
如果你在OOP中使用编译时编织,你通常会有这样的代码(C#示例):
[Log]
public void SaveOrder(Order order)
{
// Implementation goes here...
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是,虽然问题是分开的,但它们仍然是耦合的.除非重新编译,否则无法决定不登录SaveOrder.
使用计算表达式有点像:
log { return saveOrder order }
Run Code Online (Sandbox Code Playgroud)
同样,横切关注点是编制与实施在一起.
然而,在相似性结束的地方,可以使用一元组合子将关注点组合在一起,这在编译时编织中是不可能的.在OOP中,您不能轻易地采用不记录的方法,并且在将对象组合在一起时"神奇地"使其记录.
另一方面,使用monad,您可以使用纯函数并使用monadic上下文进行组合.这种后来绑定的日志记录在结构上等同于使用装饰器.
因此,只要将这些代码推迟到应用程序的入口点(其组合根),我认为将计算表达式用于横切关注点是合适的.
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |