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
Application Design 勉強会 #3
Search
k-kohey
July 12, 2019
Programming
0
89
Application Design 勉強会 #3
k-kohey
July 12, 2019
Tweet
Share
More Decks by k-kohey
See All by k-kohey
ゲームボーイアドバンスでSwiftを動かそう
k_koheyi
0
960
Swift Package Mangerのバグを直した話
k_koheyi
2
1.4k
swift-async-algorithms...? へえ…面白そうじゃん…?
k_koheyi
3
1.5k
[社内勉強会]Parchment-swiftの実装説明
k_koheyi
0
120
[社内勉強会]Combineの説明
k_koheyi
0
30
あるインスタンスの取る値が 何パターンあるか数えてみるンゴ!
k_koheyi
1
150
Tuistを用いた Xcode Project管理の紹介
k_koheyi
0
190
SwiftでわかるSOLID原則 iOSDC 2020
k_koheyi
3
2.7k
Visitorパターン
k_koheyi
0
170
Other Decks in Programming
See All in Programming
ナレッジイネイブリングにAIを活用してみる ゆるSRE勉強会 #9
nealle
0
170
Datadog DBMでなにができる? JDDUG Meetup#7
nealle
0
160
クックパッド検索システム統合/Cookpad Search System Consolidation
giga811
0
140
未経験でSRE、はじめました! 組織を支える役割と軌跡
curekoshimizu
1
200
TCAを用いたAmebaのリアーキテクチャ
dazy
0
220
バッチを作らなきゃとなったときに考えること
irof
2
550
責務と認知負荷を整える! 抽象レベルを意識した関心の分離
yahiru
9
1.5k
ソフトウェアエンジニアの成長
masuda220
PRO
12
2.2k
Swift Testingのモチベを上げたい
stoticdev
2
200
Visual StudioのGitHub Copilotでいろいろやってみる
tomokusaba
1
220
Domain-Driven Design (Tutorial)
hschwentner
13
22k
sappoRo.R #12 初心者セッション
kosugitti
0
280
Featured
See All Featured
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
175
52k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7.1k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Designing on Purpose - Digital PM Summit 2013
jponch
117
7.1k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1.1k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
The Cost Of JavaScript in 2023
addyosmani
47
7.4k
Typedesign – Prime Four
hannesfritz
41
2.5k
Rebuilding a faster, lazier Slack
samanthasiow
80
8.9k
Java REST API Framework Comparison - PWX 2021
mraible
29
8.4k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Transcript
"QQMJDBUJPO%FTJHO ษڧձ ষ ஜେֶ ใϝσΟΞֶྨ ޱ ߤฏ 1
Ϧείϑͷஔݪଇʢ-41ʣ 2
Ϧείϑஔͷݪଇʢ-41ʣ 「派⽣型はその基本型と置換可能でなければならない.」 この原則に反すると,OCPにも反することとなりプログラムが脆くなる. - 関数fがある基本クラスAをその引数に取り - Aの派⽣クラスCを関数fに渡した際において異常を起こした…とする - この場合にクラスCはLSPに従わないという LSPはOCPを有効にする⼿段の1つであり
あるモジュールに修正を施さずに拡張する⽅法として,基本型と派⽣型の置換性という形で表している 3
Ϧείϑஔͷݪଇͷྫ • 「派⽣型はその基本型と置換可能でなければならない.」 • この原則に反すると,OCPにも反することとなりプログラムが脆くなる. 4 • UserやBookがEntityの代わりとして扱えないことに よって,LSP違反が起きている. •
Entityがidentifierを持つことを担保すればこの問題 は起きない • また,Entityの種類が増えると分岐が増えるので OCP違反をしている. • LSP違反は⾃然にOCP違反を引き起こす.
Ϧείϑஔͷݪଇʢ-41ʣ • 「派⽣型はその基本型と置換可能でなければならない.」 • この原則に反すると,OCPにも反することとなりプログラムが脆くなる. 5 • UserやBookがEntityの代わりとして扱えないことに よって,LSP違反が起きている. •
Entityがidentifierを持つことを担保すればこの問題 は起きない • また,Entityの種類が増えると分岐が増えるので OCP違反をしている. • LSP違反は⾃然にOCP違反を引き起こす. この例では,単なる継承によって解決する. 継承によってLSPを満たせない場合はあるのか?
ܧঝʹΑͬͯෳࡶԽ͞Εͨ-41ҧͷྫ • この⻑⽅形を表すRectangleViewに加えて正⽅形を表すSquareViewを追加する必要が出てきたケース. • 継承はIS-A(「である」)の関係であるといわれている. • 正⽅形は⻑⽅形であるのでSquareはRectanbleのサブクラスになりそうだ. 6
ܧঝʹΑͬͯෳࡶԽ͞Εͨ-41ҧͷྫ • 本来⼀辺を設定できれば良いが,継承によって不要なメソッドを受け継いでしまった. • したがって,下記のように両辺の⻑さが等しいことを担保した. • 結果,Squareの性質を担保することが出来た! 7
ܧঝʹΑͬͯෳࡶԽ͞Εͨ-41ҧͷྫ • 結果,Squareの性質を担保することが出来が…… • クライアントによっては下記のコードのような間違いが起きる. 8 関数fにSquareViewを与えたときに,assertでエラーが発⽣する. SquareViewはIS-Aの関係を満たしており正⽅形本来の性質も満たしている. じゃあ,このコードには正当性があり,間違っているのはクライアント?
ܧঝʹΑͬͯෳࡶԽ͞Εͨ-41ҧͷྫ • 結果,Squareの性質を担保することが出来が…… • クライアントによっては下記のコードのような間違いが起きる. 9 関数fにSquareViewを与えたときに,assertでエラーが発⽣する. SquareViewはIS-Aの関係を満たしており正⽅形本来の性質も満たしている. じゃあ正当なのか? このコードが間違っているのだろうか?
LSPに準拠するためにはIS-Aの関係では不⼗分. 「振る舞い」の同等性も必要! 誰もが合理的だと思う振る舞いをIS-Aに持たせる.
ܖʹΑΔઃܭ • 合理的な仮定を明確にするテクニック. • あるメソッドについての事前条件と事後条件を決めておくことによって,そのメソッドを利⽤する⼈が 必要としている振る舞いを知る事ができる. • 事前条件: そのメソッドを実⾏する前に成⽴していなければいけない条件 •
事後条件: メソッドが終了したときに成⽴していなければならない条件 • 基本クラスをインタフェースにした場合に,クライアントが理解しているのは基本クラスの事後条件と 事前条件のみ • 派⽣クラスの事前条件は基本クラスに課せられている事前条件より強くしてはいけない. • 派⽣クラスの事後条件は基本クラスの事後条件より弱くしてはいけない. Square::setWidthはRectanbleより事後条件が弱い.よって設計契約に反する. -> 振る舞いの同等性が担保されていない 10
ܦݧଇʹґΔ͓खܰ-41ҧνΣοΫ • Overrideによって関数の機能が劣化しているケース • 基本クラス以下のことしか出来ないのであれば置換は不可能. • 基本クラスでは投げない例外を派⽣クラスによって投げられているケース • 基本クラスの利⽤者がその例外を期待していないのでれば,置換不可能. •
= 事前条件が強まってる?? 11
ґଘੑٯసͷݪଇʢ%*1ʣ 12
ґଘੑٯసͷݪଇʢ%*1ʣ 上位のモジュールは下位のモジュールに依存してはならない. どちらのモジュールも抽象に依存すべきである. 抽象は実装の詳細に依存してはならない.実装の詳細が抽象に依存すべきである. • 悪しき⼿続き型プログラミングでは⽅針が実装に依存する • 抽象と実装の詳細を完全に切り分けることによって変更に強くなる • 再利⽤性も⾼まる
13
%*1ͷϞνϕʔγϣϯ • アプリケーションの⽅針といったビジネスモデルを含む上位モジュールが下位のモジュールに依存する と,下位のモジュールの変更が上位モジュールに影響する. • それは本来逆であるべき.⾃分たちが使いたいのは上位のモジュールであるはず. 14 ґଘੑͷٯస 下位モジュールから上位モジュールへの
%*1ʹΑͬͯӨڹ͕ൖ͠ʹ͍͘֊ߏΛ࡞Δ • オブジェクト指向の⾔語では明確に定義付けられた階層を持つ • 上位のモジュールがインタフェースを持つことによって,下位のモジュールは上位のモジュールに依存 する. • インタフェースによって詳細の実装を隠蔽されているため上位のモジュールは下位のモジュールに依存 しない. 15
本書p165より転載 本書p165より転載
%*1ҧͷྫ 16 Button Lamp
%*1ద߹ͷྫ 17 Button SwifthableServer Lamp
%*1ద߹ͷྫ 18 Button SwifthableServer Lamp Buttonによって制御されるオブジェクトは全てButtonServerに準拠しなくてはいけない,というの は問題.Switchなどを操作することもある. ー> 命名を⼀般的にすることによって解決
நʹґଘͤΑ • DIPは抽象に依存せよ,という経験則とも⾔える. • 具体的なクラスへのポインタやリファレンスを保持するような変数があってはならない • 具体的なクラスから派⽣するクラスがあってはならない • 基本クラスで実装されているメソッドを上書きするようなメソッドがあってはならない. 19
Πϯλϑʔεͷݪଇʢ*41ʣ 20
ΠϯλϑΣʔεͷݪଇ • 太ったクラスはそれを利⽤するクライアント同⼠で良くない問題を起こす. • 例えば,あるクライラントが依存先のクラスに変更を要求すると,別のクラスに変更の影響が伝搬する 可能性がある(OCP違反) • クライアントごと(もしくはクライアントのグループ)に必要なメソッドを切り出したインタフェース を作成することによって,この問題は解決できる. •
結果,クライアントは⾃⾝が利⽤しないメソッドとの依存関係を切り捨てられる. 21 ΠϯλϑΣʔεͷ クライアントに⾃⾝が利⽤しないメソッドへの依存を強要してはならない
ΠϯλϑΣʔεͷྫ • これらの定義を⽤いて⻑時間ドアが空いているとロックされるTimedDoorを実装する. 22
ΠϯλϑΣʔεͷྫ • よくある⼿法(らしい) • この⼿法ではTimerDoor⾃体がタイムアウトの通知を 受けられる利点がある⼀⽅でDoorがTimerDoorに依存 してしまう問題がある. • これはインタフェースを太らすインタフェースの汚染 である.
• また,この⼿法はLSPに違反する. 23 • これらの定義を⽤いて⻑時間ドアが空いているとロックされるTimedDoorを実装する.
ΠϯλϑΣʔεͷྫ • よくある⼿法(らしい) • この⼿法ではTimerDoor⾃体がタイムアウトの通知を 受けられる利点がある⼀⽅でDoorがTimerDoorに依存 してしまう問題がある. • これはインタフェースを太らすインタフェースの汚染 である.
• また,この⼿法はLSPに違反する. 24 • これらの定義を⽤いて⻑時間ドアが空いているとロックされるTimedDoorを実装する. インタフェースの分離=クライアントの分離 DoorとTimeClientは異なるクライアントにインタフェースを 提供する.ならばインタフェースを分離させるべき.
ΠϯλϑΣʔεͷྫ 25 Adapterパターンを⽤いた⽅法 多重継承を⽤いた⽅法
Ҿ༻ • ロバート・C・マーチンほか.アジャイルソフトウェア開発の奥義 第 2版 オブジェクト指向開発の神髄と匠の技. SBクリエイティブ, 2008 26