Functional programming 像Elixir这样的函数式语言处理大型进程链的惯用方式是什么?

Functional programming 像Elixir这样的函数式语言处理大型进程链的惯用方式是什么?,functional-programming,elixir,Functional Programming,Elixir,举一个例子,比如处理客户结账的服务/功能,其中涉及许多步骤:服务器(例如)检查库存、验证欺诈、向信用卡收费、扣除库存、结束购买、向客户发送电子邮件、通知后端/处理人/仓库,然后返回http请求 在面向对象的语言中,我会用一种方法来解决这个问题,构建一个服务对象,让它同步有序地执行这些步骤,在出现问题时进行分支(甚至可能使用状态机) 然而,当我想到如何用一种类似于药剂的语言来处理这个问题时,我唯一能想到的解决办法是一条长链的管道——这就像是在仙丹世界中的一种反模式,特别是当你考虑分支时。p> 我的

举一个例子,比如处理客户结账的服务/功能,其中涉及许多步骤:服务器(例如)检查库存、验证欺诈、向信用卡收费、扣除库存、结束购买、向客户发送电子邮件、通知后端/处理人/仓库,然后返回http请求

在面向对象的语言中,我会用一种方法来解决这个问题,构建一个服务对象,让它同步有序地执行这些步骤,在出现问题时进行分支(甚至可能使用状态机)

然而,当我想到如何用一种类似于药剂的语言来处理这个问题时,我唯一能想到的解决办法是一条长链的管道——这就像是在仙丹世界中的一种反模式,特别是当你考虑分支时。p> 我的第二个想法是,每一步都有它自己的功能(感觉很习惯),它需要额外的参数来说明购买的状态。在这种情况下,
validate\u fraud
操作可以使用
{purchase,fraud\u passed}
信息调用
charge\u credit\u card
,然后在完成时调用行中的下一个。然而,这意味着每个函数都需要知道它在一个链中的位置,这同样感觉像一种气味(而且每个函数都需要有逻辑来处理不同的传入“状态”)


Elixir中处理OO世界将使用服务对象解决的情况的惯用方法是什么?

该语言的功能性质不能暗示任何业务规则。如果链看起来像您所描述的,那么使步骤异步是没有价值的(事实上也不可能),因为
validate\u fraud
inventory\u check
之前和
charge\u credit
之后都没有任何意义

在这种情况下,解决方案与OO服务非常相似:可能会产生一个流程(在这种特殊情况下),该流程将管道化所有步骤:

task = Task.async(fn ->
   check inventory()
   |> validate fraud()
   |> charge()
   |> deduct_inventory()
   |> close_purchase()
   |> email_customer()
   |> notify_handler()
   |> return_http_request()
end)

现在任务有了一个很好的特性,可以检查任务是否已完成,并有自己的超时。调用方代码可以简单地调用
任务。等待/2
阻止调用方,直到任务完成,或者,更好的是,它可以使用
任务等待,比如说3秒钟。产生
并以结果(如果任务完成)或“承诺”进行响应如果执行时间较长。

该语言的功能性质不能暗示任何业务规则。如果链看起来像您所描述的,那么使步骤异步是没有价值的(事实上也不可能),因为
validate\u fraud
inventory\u check
之前和
charge\u credit
之后都没有任何意义

在这种情况下,解决方案与OO服务非常相似:可能会产生一个流程(在这种特殊情况下),该流程将管道化所有步骤:

task = Task.async(fn ->
   check inventory()
   |> validate fraud()
   |> charge()
   |> deduct_inventory()
   |> close_purchase()
   |> email_customer()
   |> notify_handler()
   |> return_http_request()
end)

现在任务有了一个很好的特性,可以检查任务是否已完成,并有自己的超时。调用程序代码可以简单地调用<代码>任务。AUSE/2 在完成任务之前阻止调用方,或者更好的是,它可能会等待,比如说,用“代码>任务”3秒。屈服< /代码>并用结果来回答,如果完成了,或者“承诺”,如果执行时间更长。将大量信息耦合到一段代码中。这对你来说也应该是一种反模式的味道。@Onriocatenacci“服务对象”可能会将所有十个检查委托给不同的模块,从而产生12行代码,即使每个
委托都有自己的行。这是一个公平的分数。这听起来并不像他说的那样。有一件事要考虑的是,“服务对象”将大量信息耦合到一段代码中。这对你来说也应该是一种反模式的味道。@Onriocatenacci“服务对象”可能会将所有十个检查委托给不同的模块,从而产生12行代码,即使每个
委托都有自己的行。这是一个公平的分数。虽然听起来他不是那个意思。