F# - 纯功能设计,而不是oop设计

use*_*784 2 f# domain-driven-design functional-programming

我想创建一个由三个代理组成的简单"多代理"系统.对于每个代理程序,都会创建一个封装邮箱处理器的类型.所有代理(位置,id等)和函数(sendMessage,move)都有共同的属性,代理与邮箱处理器的实现(消息的处理方式)不同.此外,它们可能因特定代理商特有的其他功能而不同.每个代理还应该包含(作为其属性之一)其他代理的列表,它将向其发送消息.这是一个非常简单的模型,我计划在F#中使用邮箱处理器.

在OOP中,这意味着创建代理接口(或抽象类),并且所有特定代理都将使用自己的实现从此接口继承.

我知道OOP在F#中是可行的,但我宁愿坚持纯粹的功能设计.但是,在我看来,OOP是这种情况下最合适的方法.如果您能就功能(F#)设计给我任何想法,我会很高兴吗?谢谢.

Tom*_*cek 17

首先,F#中的功能风格面向对象风格并没有真正发生冲突.

  • 功能样式包括使用不可变类型,没有副作用的纯函数和F#数据类型,如区分联合,函数等.

  • 面向对象的风格更侧重于如何组织代码(使用类和接口),但代码仍然可以纯粹功能而不使用任何可变状态.

在基于代理的系统中,在代理的实现中使用功能样式是有意义的,但是使用类来组织代理.我认为这可能是F#中的最佳实践(另请参阅有关在MSDN上封装F#代理的文章).

在您的示例中,您说代理会保留其发送消息的其他代理的列表.有一些值得考虑的选择(如果你想避免接口):

  • 公开F#事件(Event<'T>).这样,代理只是公开通知,而不必显式管理其他代理的列表(此设计也允许其他类型的订户).

  • 保留一系列功能.如果您只需要向其他代理发送消息,那么您基本上只需要一个具有单个方法的接口.在这种情况下,您可以保留一系列功能,例如
    Message -> unit.

我通常更喜欢暴露事件 - 这样,系统耦合不那么紧密,您可以更轻松地以各种方式组合代理(它们不必实现特定的接口组合).本文从更高层次的角度讨论基于代理的体系结构,也可能有用.