つまりハンバーガーはclean architectureだったんだよ!
ΩΩΩ < ナ、ナンダッテー
この記事で説明したいこと
clean architectureを(実際の実装を含めて)マク○ナル○に例えて説明したいと思います!
なんでマク○ナル○?
早い・安い・美味い、エンジニアの気絶のお供と言えばマク○ナル○だからです!(関係ない)
キャッチーなタイトルだと書くモチベがあがりますよね!
ファーストフードでは誰がオーダーを受けようが誰が料理しようが基本的に同じ味で提供されますね。
例えばキッチンのスタッフが入れ替わっても、レジの人は気にせずキッチンへのオーダーを通す事ができますが、これはclean architectureの疎結合に似ています。
またclean architecture(に限らない話ですが)はdbの依存関係を極力少なくしているのでdbの移行などでも最小限の工数で済む。というメリットがあります。
今回inputのインターフェースを4つ。outputのインターフェースを計5つ盛りだくさんで実装しています。
この記事のターゲット
clean architectureについて解説してる有用な記事はたくさんありますが、clean architecture自体が難しい概念なので中々理解できない方が対象です。
かくゆう私も わからなくなることがたまによくあります!てへぺろ
ソースコードはこちら
動作サンプル
左側:スタッフが確認できるモニター
項目 | 概要 | 説明 |
---|---|---|
reserve | オーダー受付 | オーダーリクエストを受け付けて予約番号が発行されるとこちらに表示 |
assemble | 調理中 | 調理可能な数(サンプルは3)に空きがあればreserveのオーダーがこちらに移動 |
complete | オーダー完成 | 調理が完成したオーダーはyummyフォルダにjsonファイルとしておかれこちらに移動 |
pass | 引き渡し済み | yummyフォルダにあるjsonファイルを削除するとこちらに移動 |
右側:オーダーを注文するAPIなど
種類 | リクエスト方法 | リクエスト受付 | 補足 |
---|---|---|---|
mobile | 1234port http:post:json | echo | |
PC | 2345port http:post:json | gin | |
delivery | 3456port grpc | grpc | ウー○ー的な提携業者を想定 |
register | jsonファイル指定場所に配置 | ファイル監視 |
ディレクトリ設計
全体の設計をStandard Go Project Layout
internal内のディレクトリ設計をclean Architecture
ディレクトリ設計詳細
全体
ディレクトリ | 説明 |
---|---|
build | Dockerfile |
cmd | main.go |
config | .bashrc |
internal | 別テーブル参照 |
pkg | 共通ライブラリ |
script | entrypoint.shとオーダー用スクリプト |
storage | ログ・エラーログ |
web | index.htmlとvueファイルなど |
yummy | オーダー完成場所(jsonファイル) |
internal
ディレクトリ | 説明 |
---|---|
1_framework_driver | Frameworks & Drivers レイヤー |
1_framework_driver/db | 食材の保管 |
1_framework_driver/db/freezer | MySQL:冷凍庫 パティを保存 |
1_framework_driver/db/refrigerator | PostgreSQL:冷蔵庫 野菜、チーズなどの保存 |
1_framework_driver/db/shelf | MongoDB:棚 バンズを保存 |
1_framework_driver/external_interface | オーダーモニター、商品の引き渡し |
1_framework_driver/external_interface/monitor | websocket&vue:オーダーモニター |
1_framework_driver/external_interface/shipment | jsonファイルを商品の引き渡しとする |
1_framework_driver/web_ui | オーダー受け付け |
1_framework_driver/web_ui/mobile | echo:モバイル注文 |
1_framework_driver/web_ui/pc | gin:pc注文 |
1_framework_driver/web_ui/delivery | grpc:ウー○ー的な提携業者からの注文 |
1_framework_driver/web_ui/register | ファイル監視:レジ注文 |
2_interface_adapter | Interface Adapters レイヤー |
2_interface_adapter/controller | web_uiからのオーダーをusecaseに渡す |
2_interface_adapter/gateway | usecaseからDBへのリクエストを渡す |
2_interface_adapter/presenter | usecaseからexternal_interfaceへリクエストを渡す |
3_application_business_rule | Application Business Rules レイヤー |
3_application_business_rule/usecase | ユースケース |
4_enterprise_business_rule | Enterprise Business Rules レイヤー |
4_enterprise_business_rule/entity | ビジネスロジック 調理(野菜を切る、パティを焼くなど) |
オーダーフロー
framework_driver/web_ui
- web_uiのデータ型をControllerに持ち込まないようにentityのデータ型に変換
- オーダー番号発行
- オーダー ※オーダー番号を即時返却する必要があるため、Controllerにてチャネルを使用
- オーダー番号を返却
framework_driver/db
- dbの違いはこのパートで解消
- 必要な食材を取得(デクリメント更新)
framework_driver/external_interface
- オーダー情報を随時更新するモニター(http://localhost:4567/)
- 商品の出荷(backend/yummyディレクトリ)
- 商品の出荷履歴(backend/storage/logディレクトリ)
interface_adapter/controller
- オーダー番号発行
- オーダー処理
interface_adapter/presenter
usecaseからexternal_interfaceへ商品またはオーダー更新情報などを渡すパート
interface_adapter/gateway
application_business_rule/usecase
controllerからのオーダーを受け取り、目的に応じて以下に処理を渡すパート
- オーダー内容の解析・調理(データの解析・変更)は enterprise_business_rule/entity
- 食材の取り出し(DB更新)は interface_adapter/gateway
- オーダー情報のモニタ表示・商品の出荷は interface_adapter/presenter
enterprise_business_rule/entity
- 調理に必要な食材数をカウントする
- 食材を調理する
動作確認
git clone git@github.com:yabeyuji/macOnalO-chot-dekiru.git
cd macOnalO-chot-dekiru
make build
make up
# オーダーは backend/script/order ディレクトリ内を参照
最後に
うーん。よく見るとハンバーガーのバンズ/レタス/パティ/トマト/バンズ もclean architectureが見えてきますね(タイトル回収)
疲れてるとclean architectureがゲシュタルト崩壊します。(初心者にありがち)
こんなときはハンバーガーを食べて寝るに限りますね。
ちなみに私はサブウェイ派なのでBLTを食べます!
メキシカンミートタコス おいしそう
参考URL
https://qiita.com/t2-kob/items/02a76572693130c9a66e
https://qiita.com/nrslib/items/a5f902c4defc83bd46b8
https://qiita.com/koutalou/items/07a4f9cf51a2d13e4cdc
https://www.m3tech.blog/entry/2020/02/07/110000
https://www.lifull.blog/entry/2020/10/13/110000