概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Don't blindly apply software patterns | Arkency Blog
- 原文公開日: 2020/06/23
- 著者: Miroslaw Praglowski
- サイト: arkency
ソフトウェアパターンを闇雲に適用しないこと(翻訳)
今日はランニングで汗を流した後、その日のポッドキャストエピソードをいくつか追いかけたのですが、Mariusz Gilが公開している素敵な「Better Software Design」で取り上げられていたSagaパターン(後述)やプロセスマネージャーに関して、私のコメントを本記事で共有したいと思います。
Mariuszの対談の相手はKuba Pilimonでした。2人の開発者がいわゆるDDD(ドメイン駆動開発)でソフトウェアを設計する方法について議論するというシリーズの第3エピソードでした(このポッドキャストはポーランド語ベースですが、Alberto Brandoliniへのインタビューのようなエピソードは英語で録音されています)。
今回のポッドキャストを聞いていて全般にとても興味を惹かれましたが、私からいくつかコメントしたいことがあります。
パターンは「銀の弾丸」ではない
MariuszとKubaは、映画館の座席予約を例にSagaパターンを話題にしていました。モデルはいたってシンプルです。各Seat
は1つの集計(aggregate)になっていて、席を4つ予約するには、「4件の予約がすべて処理される」または「払い戻し操作をすると予約はすべて解除される」ようにするために「Saga」を1つ持つ必要があります。
コード例は以下のようなものでした(擬似コードにつきあしからず)。
# Ruby風味の擬似コード(時間軸は下に進む)
プロセスA プロセスB
book_seat('A-1') book_seat('A-3')
book_seat('A-2') book_seat('A-4')
book_seat('A-3') book_seat('A-5')
book_seat('A-4')
#... ここで席A-3やA-4の予約が(プロセスBによって予約済みなので)失敗したときに、プロセスAが払い戻し操作を開始する【チェック】
見た目には随分シンプルそうです。プロセス(Saga)が2つあり、各Sagaは席の予約を試み、最初のSagaが勝ちます。もう一方のSagaは払い戻し操作を開始して、予約した席を解放します。
しかし現実はそう簡単にはいきません。
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery
— Mathias Verraes (@mathiasverraes) August 14, 2015
分散システムにおける難問は2つしかない。「2: デリバリーを確実に1回だけ行うこと」「1. メッセージの順序を保証すること」「2: デリバリーを確実に1回だけ行うこと」
以下のような状況を想像してみましょう。
# Ruby風味の擬似コード(時間軸は下に進む)
プロセスA プロセスB
book_seat('A-4') book_seat('A-3')
book_seat('A-2') book_seat('A-4')
book_seat('A-3') book_seat('A-5')
book_seat('A-1')
この場合の結果はどうなるでしょう?A-3は既にプロセスBに押さえられているので、プロセスAはSagaを完了できません。そしてA-4は既にプロセスBに押さえられているので、プロセスBもSagaを完了できません。プロセスAとプロセスBが両方とも払い戻し操作を開始して予約を解放しようとします。運が悪いと、予約申し込みが殺到しているのにこれらの席は売れなくなってしまいます。ビジネス用語で言い換えれば、顧客は失望し、売上は失われてしまうわけです。
もうひとつコメントしたい例は、Sagaパターンのよく使われる利用例です(飛行機やホテルやレンタカーの予約と、予約に失敗した場合の解放)。
ソフトウェアパターンを闇雲に適用しないこと
MariuszとKubaは、これらを拡張するさまざまなシナリオを話題にしました。しかし私がそこで聞けなかった話題、かつこうした例を目にしたときに私にとって常に問題となる点は次のとおりです。
飛行機とホテルとレンタカーを予約しようとして空きがない場合、人は何を期待するでしょうか?もしかしたら違うかもしれませんが、自分なら飛行機とホテルを予約したときに「レンタカーを予約できませんが、どうなさいますか?」とシステムがこちらに尋ねてくれることを期待します。飛行機とホテルは予約できたのに、レンタカーが予約できないという理由で全部キャンセルするようなアプリはきっと好きになれないでしょう。
まともなソリューションとは
とにかくその業種や業界に通じた専門家に質問することです。そうした専門家は業務として毎日この種の問題を扱っているのが普通です。「ソフトウェア設計パターンを闇雲に適用すべきではない」と申し上げたいのはそういう意味です。パターンで押し切るより前に、その道の専門家に現実の問題解決方法を聞くことです。
開発チームを雇いたいとお考えの方へ。(めったにないことかもしれませんが)現時点で私たちArkencyの業務はいっぱいで新規プロジェクトはほとんど手掛けておりませんが、2020年第3四半期からはお引き受け可能です。ご用命がございましたらお気軽に弊社フォームまでどうぞ。