Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
GoとDDDでモバイルオーダープラットフォームを 型安全に作り直した話
Search
takuya kikuchi
February 22, 2022
0
83
GoとDDDでモバイルオーダープラットフォームを 型安全に作り直した話
2022-02-22 / GeekGig 『DONUTS×Showcase Gig』〜Goでゼロから作り直した話〜 の登壇資料です
takuya kikuchi
February 22, 2022
Tweet
Share
More Decks by takuya kikuchi
See All by takuya kikuchi
生成AI時代のソフトウェアエンジニアが持つべきケイパビリティを考える
tkikuchi1002
8
4.8k
RAGをテーマに考える、LLMの認知アーキテクチャとソフトウェア設計
tkikuchi1002
3
1.1k
生成AIの不確実性と向き合うためのオブジェクト指向設計
tkikuchi1002
3
6.5k
Azure AI SearchとPromptFlowではじめるRAG
tkikuchi1002
2
1.2k
法人向けChatGPTにおける Azure OpenAI Serviceの課題解決の過程と現在
tkikuchi1002
2
1.9k
LLMエンジニアリングを加速させるソフトウェアアーキテクチャ
tkikuchi1002
2
5.2k
WebAPIのバリデーションを、型の力でいい感じにする
tkikuchi1002
0
68
Kotlinのcoroutine、async/awaitと同じでしょ?って思ってたけど意外と洗練されててすごいなぁって思った話をさせてほしい
tkikuchi1002
0
89
使いやすいインターフェースについて考える
tkikuchi1002
0
28
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Adopting Sorbet at Scale
ufuk
73
9.1k
RailsConf 2023
tenderlove
29
900
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
What's in a price? How to price your products and services
michaelherold
243
12k
The Language of Interfaces
destraynor
154
24k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
130
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Typedesign – Prime Four
hannesfritz
40
2.4k
Transcript
confidential GoとDDDでモバイルオーダープラットフォームを 型安全に作り直した話 takuya kikuchi @ Showcase Gig 1 2022-02-22
GeekGig 『DONUTS×Showcase Gig』〜Goでゼロから作り直し た話〜
confidential ©Showcase Gig 2 発表者 - capybara (takuya kikuchi) -
twitter: @_pochi - Engineer Group Manager @ Showcase Gig
confidential ©Showcase Gig 3 GoとDDDでモバイルオーダープラットフォームを型安 全に作り直した話
confidential ©Showcase Gig 4 GoとDDDでモバイルオーダープラットフォームを型安 全に作り直した話
confidential ©Showcase Gig 5 モバイルオーダープラットフォーム モバイルオーダーと一言でいっても、色々あります
confidential ©Showcase Gig 6 モバイルオーダープラットフォーム モバイルオーダーと一言でいっても、色々あります 注文シーン 受け取りシーン
confidential ©Showcase Gig 7 モバイルオーダープラットフォーム モバイルオーダーと一言でいっても、色々あります 自宅から 注文シーン 受け取りシーン
confidential ©Showcase Gig 8 モバイルオーダープラットフォーム モバイルオーダーと一言でいっても、色々あります 自宅から 注文シーン 受け取りシーン 店舗で受け取り
confidential ©Showcase Gig 9 モバイルオーダープラットフォーム モバイルオーダーと一言でいっても、色々あります 自宅から 注文シーン 受け取りシーン 店舗で受け取り
ロッカーで受け取り
confidential ©Showcase Gig 10 モバイルオーダープラットフォーム モバイルオーダーと一言でいっても、色々あります 自宅から 注文シーン 受け取りシーン 店舗で受け取り
ロッカーで受け取り 店内で食べながら
confidential ©Showcase Gig 11 モバイルオーダープラットフォーム モバイルオーダーと一言でいっても、色々あります 自宅から 注文シーン 受け取りシーン 店舗で受け取り
ロッカーで受け取り 店内で食べながら テーブルまで配膳
confidential ©Showcase Gig 12 モバイルオーダープラットフォーム O:der Table: 店内飲食 O:der Kiosk:
Kiosk端末からの注文(イートイン・テイクアウト) O:der ToGo: テイクアウト The Label Fruit: テイクアウト(ロッカー受け取り) O:der Platform: 各プロダクトの共通基盤 and more
confidential ©Showcase Gig 13 モバイルオーダープラットフォーム O:der Table: 店内飲食 O:der Kiosk:
Kiosk端末からの注文(イートイン・テイクアウト) O:der ToGo: テイクアウト The Label Fruit: テイクアウト(ロッカー受け取り) O:der Platform: 各プロダクトの共通基盤 and more
confidential ©Showcase Gig 14 GoとDDDでモバイルオーダープラットフォームを型安 全に作り直した話
confidential ©Showcase Gig 15 モバイルオーダープラットフォームを作り直すぞ! DDDをやるぞ!
confidential ©Showcase Gig 16 DDD (ドメイン駆動設計) ドメイン駆動設計とはソフトウェアの設計手法である。 「複雑なドメインの設計は、モデルベースで行うべき」であり、また「大半のソフト ウェアプロジェクトでは、システムを実装するための特定の技術ではなく、ドメイ ンそのものとドメインのロジックに焦点を置くべき」であるとする。
出典: https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9 %A7%86%E5%8B%95%E8%A8%AD%E8%A8%88
confidential ©Showcase Gig 17 わからん
confidential ©Showcase Gig 18 なんとなくやってみよう 書籍などを参考にしつつ、チームとしてこれくらいの理解でやってみた • いいプロダクトにはいいドメインモデルがあるらしい • ユビキタス言語を定めて、それを使って対話をするべきらしい
• エンジニアだけでなく、ドメインエキスパートを集めてモデリングをするとい いらしい • ドメインモデルと実装は一致しているといいらしい • 整合性を保ちたい範囲を集約とかいうらしい
confidential ©Showcase Gig 19 ドメインモデリングした • 登場人物 ◦ プロダクトマネージャー(プロダクトに詳しい) ◦
CS(飲食店のオペレーションに超詳しい) ◦ エンジニア(詳しくなりたい) • ホワイトボードツールつかって おしゃべりした ◦ 「「注文」って何?」 ◦ 「商品って?メニューって?」 ◦ ユビキタス言語を定めていく
confidential ©Showcase Gig 20 注文って何 • お金を払う行為は伴うの? • ファミレスでの「注文」と、デリバリーサービスでの「注文」って一緒なの? •
注文の単位ってなんだろう。 ◦ 3人で1つずつ頼んだ料理は3注文? ◦ 1人で3つ料理を頼んだらそれは3注文? Oxford Languagesの定義 ちゅうもん 【注文・註文】 《名・ス他》 1. 1. 品質・数量・形・寸法等を指定して、作らせたり送らせたりすること。 「―を取る」 2. 2. こうしてほしいと指図(さしず)をし、希望すること。 「―をつける」
confidential ©Showcase Gig 21 モデルの例 ※簡略化しています
confidential ©Showcase Gig 22 GoとDDDでモバイルオーダープラットフォームを型安 全に作り直した話
confidential ©Showcase Gig 23 Goで実装するよ • 全体設計 ◦ Onion Architecture
• 今日は主にドメイン層とユースケース層の話をします
confidential ©Showcase Gig 24 こいつを忠実に実装する
confidential ©Showcase Gig 25 ドメイン層: Order struct 定義 // Order
注文モデル type Order struct { orderID types.OrderID restaurant order_vo.Restaurant orderItems []*order_vo.OrderItem orderedAt order_vo.OrderedAt orderState order_vo.OrderState } • すべてValue Objectとし、プリミティブ型は扱わない
confidential ©Showcase Gig 26 ドメイン層: CreteOrder // NewOrder 注文を新規に作成する func
NewOrder( orderID types.OrderID, restaurant order_vo.Restaurant, orderItems []*order_vo.OrderItem, orderedAt order_vo.OrderedAt, state order_vo.OrderState, ) (*Order, error) { // 注文時間から、店舗で注文受付可能か判断す る accept, err := restaurant.IsOrderAcceptable(orderedAt) if err != nil { // 何からのエラーが発生したので注文失敗 return nil, err } if !accept { // 店舗設定により注文不可なので注文失敗 return nil, errors.New("注文受付時間 外") } // 注文オブジェクト生成 return &Order{ orderID: orderID, restaurant: restaurant, orderItems: orderItems, orderedAt: orderedAt, orderState: state, }, nil } • Entity / ValueObjectの生成は、必ず 専用のコンストラクタを利用する。 • 注文作成条件を満たさないような、 不正な注文オブジェクトは 生成できないようにする • 引数なども正しいものしか 渡ってこない前提で実装できる
confidential ©Showcase Gig 27 ユースケース層: CreateOrder ユースケース層の実装 • Entity /
VOを生成して • 永続化する それだけを行う。 「この場合注文できていいんだっ け?」というロジックはすべてドメ インモデルの中に含まれているの で、Usecase層は何もしなくてよ い。 // Create 注文を受け付ける func (o *CreateUseCase ) Create(ctx context.Context, input CreateInput ) (orderId types.OrderID, err error) { // DBトランザクション内で処理する err = o.dbClients.WritableClient. RunInWriteTx (略) (err error) { // ~~~~ 略 ~~~~ // 取得した商品情報から注文商品情報を組み立てる orderItems , err := vo.NewOrderItems (orderRequestItems , items) if err != nil { // 注文商品情報が不正 return } // 注文ステータス作成 initialState , err := vo.NewOrderState (input.InitialOrderState) if err != nil { // 注文ステータスが不正 return } // 店舗情報取得 restaurant , err := o.masterRepository. GetRestaurant (ctx, queryable, types.RestaurantID (input.RestaurantId)) if err != nil { // 店舗が不正 return } // 注文エンティティ生成 orderId = types.OrderID(numberingService. Generate()) orderEntity , err := entity.NewOrder( orderId , restaurant , orderItems , orderedAt, initialState , ) if err != nil { // 注文作成に失敗 return } // 注文を永続化 err = o.orderRepository. Persist(ctx, queryable, orderEntity) if err != nil { // ~~~~ 略 ~~~~ } return }) return orderId, nil }
confidential ©Showcase Gig 28 Goで実装したよ • DDDに従い、モデルを忠実に実装してみた ◦ モデリングが終わった頃にはほぼ実装内容も決まっていて新感覚。 ◦
ドメイン層はピュアなGo言語の世界なので、ユニットテストを書きやすい。プログラミングし てる!って気持ちになって楽しい。 • Goはゴリゴリのオブジェクト指向言語というわけではないが、十分に書ける。 ◦ Defined Typeがあるので、プリミティブ型に別名をつけるのが楽で快適 • 唯一気になるのは ◦ コンストラクタを経由しないオブジェクト生成を禁止できない ◦ (「こうすればいけるよ」募集中です )
confidential ©Showcase Gig 29 GoとDDDでモバイルオーダープラットフォームを型安 全に作り直した話
confidential ©Showcase Gig 30 おしまい