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
Scalaで始める表明プログラミング
Search
男爵
March 04, 2022
Programming
3
820
Scalaで始める表明プログラミング
『SaaSプロダクト開発のScala活用事例』の発表資料です。
https://alp.connpass.com/event/239935/
男爵
March 04, 2022
Tweet
Share
More Decks by 男爵
See All by 男爵
デッドロックを回避するリポジトリ実装の勘所
dnskimo
3
430
分析・設計・テストで活きる ユースケースシナリオの書き方と使い方
dnskimo
4
9k
JIRAとGASで半自動化!カンバンメトリクス
dnskimo
3
1.1k
PHPではじめるCQRSっぽいやつ
dnskimo
9
2.8k
ユースケースシナリオのススメ
dnskimo
7
7.5k
PofEAAで考えるSaaSバックエンドの作り方
dnskimo
3
6.6k
契約による設計事始め
dnskimo
19
7.3k
PHPではじめるCQRS
dnskimo
5
3.4k
PofEAAで読み解くDoctrine2
dnskimo
3
1.7k
Other Decks in Programming
See All in Programming
ドメインイベント増えすぎ問題
h0r15h0
2
290
フロントエンドのディレクトリ構成どうしてる? Feature-Sliced Design 導入体験談
osakatechlab
8
4.1k
[JAWS-UG横浜 #76] イケてるアップデートを宇宙いち早く紹介するよ!
maroon1st
0
460
17年周年のWebアプリケーションにTanStack Queryを導入する / Implementing TanStack Query in a 17th Anniversary Web Application
saitolume
0
250
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
260
php-conference-japan-2024
tasuku43
0
250
今年一番支援させていただいたのは認証系サービスでした
satoshi256kbyte
1
250
Monixと常駐プログラムの勘どころ / Scalaわいわい勉強会 #4
stoneream
0
270
KubeCon + CloudNativeCon NA 2024 Overviewat Kubernetes Meetup Tokyo #68 / amsy810_k8sjp68
masayaaoyama
0
250
PHPで作るWebSocketサーバー ~リアクティブなアプリケーションを知るために~ / WebSocket Server in PHP - To know reactive applications
seike460
PRO
2
230
useSyncExternalStoreを使いまくる
ssssota
6
1k
MCP with Cloudflare Workers
yusukebe
2
220
Featured
See All Featured
Optimising Largest Contentful Paint
csswizardry
33
3k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
170
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.5k
Git: the NoSQL Database
bkeepers
PRO
427
64k
The Pragmatic Product Professional
lauravandoore
32
6.3k
The Invisible Side of Design
smashingmag
298
50k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
A designer walks into a library…
pauljervisheath
204
24k
Thoughts on Productivity
jonyablonski
67
4.4k
Building an army of robots
kneath
302
44k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
0
97
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
111
49k
Transcript
Scalaで始める 表明プログラミング 2022/03/04 SaaSプロダクト開発のScala活用事例 @dnskimox
自己紹介 男爵 所属:Alp, Inc. / Scalebase 開発言語:Scala、Apex/LWC(Salesfore) 好きな話題:OOP、DDD、アジャイル開発 Twitter:@dnskimox
Scalaで始める表明プログラミング ▸ 契約による設計と表明 ▸ 事前条件と事後条件 ▸ 不変条件の実装方法 ▸ Eitherと組み合わせる ▸
まとめ
1. 契約による設計と表明
None
バートランド・メイヤー著 『オブジェクト指向入門 第二版』 開放/閉鎖の原則、コマンドとクエリの 分離原則、統一形式アクセスの原則、 契約による設計、単一責任選択の原 則、etc... https://en.wikipedia.org/wiki/Bertrand_Meyer
“ キーコンセプトは契約による設計(Design by Contract)である。クラスと顧客の間の関係は、お 互いの権利と義務を表した正式な同意と見なすこ とができる。すべてのモジ ュールのそのような要 求と責任の詳細な定義があって、はじめて信頼性 の高い大規模システムが実現できるのである。 『オブジェクト指向入門
第2版 原則・コンセプト 』
顧客モジュールと供給者モジュール • データを利用 • サービスを利用 お互いの権利と義務を表した正式な同意 = 契約
“ 顧客モジュールと供給者モジュールの間の契約 は、一方にとっての利益はもう一方の義務とな る。効果的かつ信頼性の高いソフトウェアを作る ということは、顧客と供給者の間で適切なコミュ ニケーションを重ねた末、ベストな妥協案にあた る契約を作成することである。 『オブジェクト指向入門 第2版 原則・コンセプト
』
意図明白なインターフェースのこと?
それもある。が、それだけではない
“ 我々に必要なのは、内部を徹底的に調べなくて も、設計要素の意味と操作の実行結果を理解で きるようにする方法である。(中略)「契約による 設計」学派は次の段階に進み、クラスとメソッドに ついて、開発者によって保証される「表明」を作 成する。 『エリック・エヴァンスのドメイン駆動設計 』
契約の形を 表明する道具 事前条件、事後条件、クラス不変表明、ループ 不変表明、etc...
2. 事前条件と事後条件
メソッドの コード本体を 表明で挟む 事前条件 コード本体 事後条件
BankAccount(銀行口座)
deposit(預け入れ)を実装
withdraw(引き出し)を実装
顧客側のメソッド呼び出し
供給者側の隠された意図 • 預け入れで残高を減らせてしまう • 「0円を引き出す」という操作ができてしまう クラス設計者の想定と異なる使われ方をしている
メソッドに但し書きをつける?
メソッドに事前条件を仕込む
供給者の意図に反した呼び出しが できなくなる
表明は 動くドキュメント コードの書き手の想定、クラスの責務の範囲、オブジェク トの「正しい状態」の定義
供給者の意図に則した呼び出しなのに何かが おかしい? 口座残高がマイナスに。それをクラス設計者は想定しているのか?
メソッドに事後条件を仕込む ensuring: 確実にする、 保証する、 確保する
事後条件に違反していることが判明!
事後条件を守るようにコードを修正
“ ルーチンの事前条件と事後条件を定義するとい うことは、とりもなおさず、ルーチンとそれを呼び 出すものの間で契約(contract)を結んだという ことである。 『オブジェクト指向入門 第2版 原則・コンセプト 』
“ 顧客モジュールと供給者モジュールの間の契約 は、一方にとっての利益はもう一方の義務となる。 効果的かつ信頼性の高いソフトウェアを作るという ことは、顧客と供給者の間で適切なコミュニケー ションを重ねた末、ベストな妥協案にあたる契約を 作成することである。 『オブジェクト指向入門 第2版 原則・コンセプト
』
義務 顧客は供給者のメソッ ドを正当な方法で呼び 出さなければならない。 事前条件によって生じる契約 利益 供給者はメソッドが呼 び出された際、特定の 仮説が満たされると保 証される。
義務 供給者はメソッドを抜け る際、定義された状態 を満たしていなければ ならない。 事後条件によって生じる契約 利益 顧客はメソッドの呼び 出し後に、特定の性質 が得られることを保証
される。 どちらのモジュールも想定すべきパターンが減る
コードがシンプルになる 起こり得ない分岐を書かなくて良い、デッドコードの抑 制、「但し書き」のコメント不要、etc...
責任の所在が明らかに 事前条件違反なら顧客側が悪い、事後条件違反なら供 給者側が悪い。修正すべきコードは明白。
3. 不変条件の実装方法
“ 事前条件と事後条件は個々のルーチンの特性 を記述する。このほかに、全てのルーチンで維持 されなければならない、クラスに共通する全体的 な特性を表す必要がある。 『オブジェクト指向入門 第2版 原則・コンセプト 』 不変条件(クラス不変表明)
“ クラス不変条件は、あらゆる操作が終わった時 のオブジェクトの状態に関する表明となる。不変 条件は、集約全体に対しても宣言することがで き、整合性に関するルールを厳密に定義する。 『エリック・エヴァンスのドメイン駆動設計 』
Scalaには不変条件を定義する構文がない
ScalaにはCase Classがある
BankAccountクラスに不変条件を 記述する • インスタンス化の際にチェックされる • copyの呼び出し時に毎回チェックされる • オブジェクトの生成から破棄まで守られ続ける *ただしイミュータブルな場合に限る
不変条件違反は即座にエラーになる
義務 全てのクラスのオブ ジェクトは、生成されて から破棄されるまで不 変条件を満たし続けな ければならない。 不変条件によって生じる契約 利益 コードベース全体にお いて、いかなるときもオ
ブジェクトが定義された 性質を満たしていると 保証される。
コードがシンプルになる 起こり得ない分岐を書かなくて良い、デッドコードの抑 制、「但し書き」のコメント不要、etc...
責任の所在が明らかに 不変条件違反はクラス内部のコードに問題がある。事前 条件かメソッドの本体を見直すべし。
ところで、表明エラーは副作用なのでは?
“ もう一つのよくある誤解は、表明を制御構造(す なわち、特殊なケースを取り扱う技術)と考えるこ とである。(中略)sqrtが事前条件を持つ場合、x < 0での呼び出しは特殊なケースではない。単純 明快、それはバグである。 『オブジェクト指向入門 第2版 原則・コンセプト
』
表明エラーが起きたら コードを修正すべし オブジェクトの状態が異常、バリデーションの不 足、事前条件が強すぎる、etc...
表明違反の修正は簡単 問題あるのコードのすぐ近くでエラーが起きる、データが破損 する前に処理が停止する、責任の所在が明白
副作用の局所化とは分けて考えよう
4. Eitherと組み合わせる
義務 供給者はメソッドを抜け る際、定義された状態 を満たしていなければ ならない。 事後条件によって生じる契約 利益 顧客はメソッドの呼び 出し後に、特定の性質 が得られることを保証
される。 事後条件を守ることを常に保証できるか?
コードの正しさだけでは抑制できな い実行時エラー ファイルアクセスエラー 存在しないパス、パーミッショ ンの不一致、ディスクの物理 的な呼称 メモリエラー メモリ割り当ての失敗、メモリ の物理的な故障 OSからのシグナル
入力デバイスからの割り込 み、中断命令、Kill データベースエラー 接続失敗、コネクション数の 超過、ロック待ち時間の超 過、SQLのシンタックスエラー ネットワークエラー コネクション確立の失敗、コネ クションの中断 外部サービスのエラー 認証失敗、外部サービス側の バリデーション、メンテナンス
“ ルーチンが契約を満たす状態で実行を終えた場 合、そのルーチンコールは成功である。成功しな ければ失敗である。(中略)何らかの特別なイベン トがルーチンの実行を中断させたときルーチンは 失敗する。そのようなイベントを「例外」という。 『オブジェクト指向入門 第2版 原則・コンセプト 』
例外は契約の 履行失敗を表す データベースエラー、ファイルへのアクセスエ ラー、メモリ確保の失敗、etc...
Eitherを使って契約の履行失敗を表す パターン
バリデーションとは何が違うの?
バリデーションはシステム境界の外から の入力を検証する仕組み
表明はシステム境界内のモジュール同 士のやり取りを定めた契約 常に真
外からのいかなる入力に対しても表明違反 を起こさないようプログラミングする 常に真
表明とバリデーションは存在目的の異なる道 具である バリデーション 表明 誰のためのもの? システムを使う人 コードを書く人 違反が起きた時、 どうする? 入力内容を改める
コードを修正する 本番稼働時に必要? 必要 必ずしも必要ではない
BankAccountオブジェクトを作る 際のバリデーション
5. まとめ
表明を使ってモジュール間の 契約を定義する 表明エラーが起きたときは コードを修正する 不変条件でデータの破損を 未然に防ぐ
表明を使ってシンプルで堅 牢なコードを書こう! ご清聴ありがとうございました You can find me at @dnskimox &
https://dnskimox.hateblo.jp/ 👦👧👨👶 😸
参考文献 ▸ オブジェクト指向入門 第二版 概念・コンセプト ▹ 11章 契約による設計:信頼性の高いソフトウェアを構築する ▹ 12章
契約が破られるとき:例外処理 ▸ エリック・エヴァンスのドメイン駆動設計 ▸ https://en.wikipedia.org/wiki/Design_by_contract ▸ https://speakerdeck.com/twada/php-conference-2016-revised ▸ https://qiita.com/kawachi/items/c3cf53e0602fb53e78e9