2017-12-28 16 views
0

顧客のチェックアウトを処理するサービス/機能のような例を考えると、サーバーは在庫の確認、詐欺の検証、クレジットカードの請求、在庫の控除、購入の終了、バックエンド/ハンドラ/ウェアハウスに通知し、http要求を返します。Elixirのような関数型言語が大規模なプロセスチェーンを扱うという慣用的な方法は何ですか?

オブジェクト指向言語では、サービスオブジェクトを構築し、これらのステップを同期して順番に実行することで、何か問題が発生したときに分岐します(ステートマシンを使用する場合もあります)。

しかし、私がエリクサーのような言語でこの問題にどのようにアプローチするかを考えると、私が思いつくことができる唯一の解決策は、エリクシルの世界の反パターンのような感じの長いパイプです特に、分岐を考慮する場合

私が持っていたもう1つの考えは、各ステップが独自の機能(慣れていると感じる)であり、購入状態の余分な議論が必要だということでした。この場合、validate_fraudアクションは{purchase, fraud_passed}の情報を持つcharge_credit_cardを呼び出し、charge_credit_cardはそれが完了したときに次の行を呼び出します。しかし、これは、各機能がチェーン内の場所を知る必要があることを意味します。これは再びにおいのように感じられます(各機能には、さまざまな着信 '状態'を処理するロジックが必要です)。

OOの世界がサービスオブジェクトで解決する状況を処理するために、エリクシールの慣用方法は何ですか?

+0

「サービスオブジェクト」は、多くの情報を1つのコードに結合することを考慮する必要があります。それはまたあなたに反パターンのにおいがするはずです。 –

+0

@OnorioCatenacci "サービスオブジェクト"は、各デリゲートがそれ自身の行で付与されていても、10行のチェッカーすべてを異なるモジュールに委譲して12行のコードにすることがあります。 – mudasobwa

+0

フェアポイント。あたかも彼がそれを意味するかのようには聞こえませんでした。 –

答えて

2

言語の機能的性質は、ビジネスルールに何も意味できません。 validate_fraudは、inventory_checkの前、またはcharge_creditの後には意味を持たないため、説明したようにチェーンが見える場合は、値がありません(実際には考えられません)。そのような場合には、解決策は、オブジェクト指向のサービスに非常によく似

されています:一つは、おそらく(この特定のケースでTask)のプロセスを生成するでしょうパイプのすべてのステップになること:今

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

タスクは素敵なを持っていますそれが自分自身のタイムアウトを持っているのであれば、それがTask.yield/2で完了しているかどうかを調べるかもしれません。呼び出し元コードは、Task.await/2を呼び出して、タスクが終了するまで呼び出し元をブロックすることができます。たとえば、Task.yieldで3秒待ってから終了した場合は結果を返すか、または "promise" if実行に時間がかかります。

関連する問題