计算表达式是面向方面编程的替代方法吗?
这是F#管理横切关注点的解决方案。
我看了下面的文章,不禁想到了AOP (即面向方面的编程)。
在文章中,作者提供了一个处理日志记录的计算表达式的示例,但它隔离了代码的实际日志记录方面,而不混淆业务逻辑的主要意图。
我的想法准确吗?
发布于 2016-08-10 05:59:52
是的,monads是一种很好的(且惯用的)方法来解决交叉关注点等问题。monad是一个更普遍的概念,但它们的用途之一是在系统中建模效果。
在FP行话中,“效果”这个词通常意味着一个副作用.许多交叉关注点,如日志记录、审计、性能监视、缓存和计量(根据定义)都有副作用。因为它们涉及到将数据‘写入’到次要的有状态资源,所以可以使用State或Writer monads建模。
其他跨领域的关注点,如认证、授权和验证,通常可以通过Reader monad (或者,可能的话,State monad)来解决。
F#计算表达式在一元组合子上提供语法糖(本质上是返回和绑定),这与Haskell的do表示法一样。然而,与Haskell相反,您必须自己为monad定义计算表达式生成器,除了少数已经内置到语言中的表达式生成器(async,seq)。
使用单一广告来解决交叉关注点是一种不同于AOP的方法。
在面向对象编程中,AOP有两种截然不同的处理方式:
正如我在我的书中解释的那样,我认为编译时编织是解决问题的一种困难和不灵活的方法。使用装潢工是实现相同目标的一种更优雅和灵活的方法。
我发言的动机是我倾向于将关切分开。
如果在OOP中使用编译时编织,通常会有如下代码(C#示例):
[Log]
public void SaveOrder(Order order)
{
// Implementation goes here...
}这里的问题是,虽然这些关切是分开的,但它们仍然是耦合的。除非重新编译,否则不能决定不从SaveOrder登录。
使用计算表达式有点类似:
log { return saveOrder order }再一次,横切的关注是与执行一起汇编的.
然而,相似之处在于,可以使用一元组合器将关注点组合在一起,这在编译时编织中是不容易的。在OOP中,您不能轻易地采用不记录的方法,当您将对象组合在一起时,“神奇地”让它记录下来。
另一方面,使用monad,您可以使用纯函数并使用一元上下文编写它。这种后期绑定的日志记录是在结构上等同于使用解码器。
因此,我认为将计算表达式用于横切关注点是合适的,只要将这些代码推迟到应用程序的入口点( 成分根)即可。
https://stackoverflow.com/questions/38860307
复制相似问题