5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

クラベスAdvent Calendar 2024

Day 23

英会話セッションの予約システムのワークフローのモデリングをやってみる

Posted at

はじめに

 Domain Modeling Made Functionalの日本語訳版である関数型ドメインモデリングが今年の夏に発売されました。日本語訳版が発売開始された時期に、知り合いのエンジニアから誘われて輪読会を週一で実施することになり、ようやく90%くらい読み切ったので、本記事では具体的な題材を取り上げてワークフローのモデリングを実践してみたいと思います。

題材

 業務フローについてある程度知っているものが良いと思い、私が個人的に大変お世話になった大学内の英会話セッションの予約確定までのフローを取り上げたいと思います。具体的には以下のフローです。

※下記シーケンス図に登場するSA(Student Assistant)は、英会話の相手をしてくれる人です。自分が在学中の時は、2割ほどが日本人、残りは外国人留学生でした。

 後半の方に登場する教務課ですが、英会話セッションに予約すると授業の成績に加点される取り決めとなっているため記述しています。教務課の方では、成績付けという別コンテキストのアクションがあると考えられます。
 今回は上記のシーケンス図に記されている事務局の業務(予約確定)のモデリングをしていきます。

文書によるモデリング

 まずは文書によるモデリングを行なっていきます。ER図やクラス図ではなく、シンプルなテキストでモデリングをすることで、以下のような利点があります。

  • 技術的なインフラストラクチャによって、モデリングが歪められることを防げる
  • 技術的な知見が無いドメインエキスパートも一緒にモデリングについて議論ができる

書籍に倣って、以下のように記してみました。

workflow "Place Booking"
    input: UnvalidatedBooking
    output: (on success):
        BookingConfirmationSent
        AND BookingPlaced
    output: (on error):
        ValidationError

    do ValidateBooking
    if booking is invalid then:
        return with ValiationError

    do CheckBooking
    if booking is not acceptable
        return UnacceptableBookingError

    do SendBookingConfirmationToStudent

    return the events

次に各サブステップの詳細をテキストで表現していきます。
入力と出力に加えて、サブステップの依存関係も明示します。

substep: "ValidateBooking"
    input: UnvalidatedBooking
    output: ValidatedBooking OR ValidationError
    dependencies: CheckSudentCodeExists, CheckBookingLimitExceeds

    check the student code syntax
    check that student code exists in CollegeSystem

    if everything is OK, then:
        return ValidatedBooking
    else:
        return ValidationError
substep: "CheckBookingDetails"
    input: ValidatedBooking
    output: AcceptedBooking OR UnacceptableBookingError

    ask SA that the booking is acceptable or not

    if booking is accepted, then:
        return AcceptedBooking
    else:
        return UnacceptableBookingError
substep: "SendBookingConfirmationToStudent"
    input: AcceptedBooking
    output: None

    send booking confirmation email to the student

一見するとGithub Actionsのworkflowのyamlファイルに似ている気がしますが、特定の技術に依存しない自然言語で記されているので、ドメインエキスパートも確認することが可能です。

型によるモデリング

文書によるモデリングを実施した後は、静的型付け言語の型システムを利用したモデリングを行なっていきます。
今回は書籍と同じくF#を用いて型を記述していきます。

入力

 まずはワークフローの入力部分であるコマンドについて見ていきます。
今回は単一のワークフローしか扱いませんが、別のワークフローが増えた場合のことを考慮して、ジェネリクスを用いて汎用的なCommand型を定義し、それを利用します。必要に応じてCommandに持たせるフィールドは増減させても良いかもしれません。

type UnvalidatedBooking = {
    BookingId: BookingId
    StudentInfo: UnvalidatedStudent
    BookingDetails: BookingDetails
}
and UnvalidatedStudent = {
    StudentCode: string
    Name: string
    Email: string
}

type Command<'data> = {
 Data: 'data
 Timestamp: DateTime
 UserId: string
}

type PlaceBookingCommand = Command<UnvalidatedBooking>

出力

 次にワークフローの出力部分を見ていきます。ワークフローはドメインイベントを返し、そのドメインイベントが別のコマンドをトリガーし、別のワークフローを開始され、...といった具合に続いていきます。
 成功時の出力と失敗時の出力をそれぞれ直積型と直和型で定義しています。

// 予約確定ワークフローの成功出力
type BookingConfirmationSent = {
   BookingId: BookingId
   EmailAddress: EmailAddress
}

type AcceptedBooking = { //SAによる確認完了時に生成される予約状態
...
}

type BookingPlaced = AcceptedBooking 

type PlaceBookingEvents {
    BookingConfirmationSent: BookingConfirmationSent
    AcceptedBooking: AcceptedBooking
}

type PlaceBookingError = 
| ValidationError
| UnacceptableBookingError

トップレベル

 最後に予約確定ワークフローのトップレベルの関数を定義します。
前述のモデリングで見てきた通り、予約の検証やSAによる予約内容のチェックの際にエラーの発生する可能性があります。そこで、このワークフローがエラーエフェクトを持つ可能性があることを型シグネチャから分かるようにしたいためResultを用いています。またプロセスが非同期であることを型シグネチャで示すために、AsyncResultというエイリアスを定義します。
 こうすることで、関数の実装の詳細を覗かずとも、関数の型シグネチャからどのような出力が得られるのかが分かります。

type AsyncResult<'success, 'failures> = Async<Result<'success, 'failures>>

type PlaceBookingWorkflow = 
   PlaceBookingCommand -> AsyncResult<PlaceBookingEvents, PlaceBookingError>

おわりに

 以上が英会話セッションの予約システムのワークフローのモデリングです。各サブステップの実装では、カリー化や部分適用、モナドなどの関数型プログラミングのテクニックを使って実現していきますが、後続記事に譲りたいと思います。今回はF#で型を記述していきましたが、今後はKotlinやTypeScriptなど、私が業務でよく用いる言語ではどのように記述していけば良いかについても探究していきたいと思います。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?