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 勉強会23-25章
Search
k-kohey
September 12, 2019
Technology
0
60
Application Design 勉強会 23-25章
k-kohey
September 12, 2019
Tweet
Share
More Decks by k-kohey
See All by k-kohey
ゲームボーイアドバンスでSwiftを動かそう
k_koheyi
0
560
Swift Package Mangerのバグを直した話
k_koheyi
2
1k
swift-async-algorithms...? へえ…面白そうじゃん…?
k_koheyi
2
1.3k
[社内勉強会]Parchment-swiftの実装説明
k_koheyi
0
100
[社内勉強会]Combineの説明
k_koheyi
0
25
あるインスタンスの取る値が 何パターンあるか数えてみるンゴ!
k_koheyi
1
120
Tuistを用いた Xcode Project管理の紹介
k_koheyi
0
150
SwiftでわかるSOLID原則 iOSDC 2020
k_koheyi
3
2.6k
Visitorパターン
k_koheyi
0
120
Other Decks in Technology
See All in Technology
AIで変わるテスト自動化:最新ツールの多様なアプローチ/ 20240910 Takahiro Kaneyama
shift_evolve
0
200
LandingZoneAccelerator と学ぶ 「スケーラブルで安全なマルチアカウントAWS環境」と 私たちにもできるベストプラクティス
maimyyym
1
130
「家族アルバム みてね」における運用管理・ オブザーバビリティの全貌 / Overview of Operation Management and Observability in FamilyAlbum
isaoshimizu
4
150
たった1人からはじめる【Agile Community of Practice】~ソース原理とFearless Changeを添えて~
ktc_corporate_it
1
200
Oracle Exadata Database Service(Dedicated Infrastructure):サービス概要のご紹介
oracle4engineer
PRO
0
9.5k
20240912 JJUGナイトセミナー
mii1004
0
130
Javaにおける関数型プログラミンへの取り組み
skrb
7
310
エンジニア向け会社紹介資料
caddi_eng
15
250k
より快適なエラーログ監視を目指して
leveragestech
4
1.3k
アプリをリリースできる状態に保ったまま 段階的にリファクタリングするための 戦略と戦術 / Strategies and tactics for incremental refactoring
yanzm
6
760
自作Cコンパイラ 8時間の奮闘
soukouki
0
750
AI活用したくてもできなかった不動産SaaSの今とこれから
nealle
0
260
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
135
6.5k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
246
1.3M
How GitHub (no longer) Works
holman
310
140k
Designing for humans not robots
tammielis
248
25k
Testing 201, or: Great Expectations
jmmastey
36
7k
Imperfection Machines: The Place of Print at Facebook
scottboms
263
13k
How STYLIGHT went responsive
nonsquared
93
5.1k
The Straight Up "How To Draw Better" Workshop
denniskardys
230
130k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
225
22k
Unsuck your backbone
ammeep
667
57k
The Illustrated Children's Guide to Kubernetes
chrisshort
47
48k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
26
1.9k
Transcript
"QQMJDBUJPO%FTJHO ษڧձ ষ ஜେֶ ใϝσΟΞֶྨ ޱ ߤฏ 1
࣍ • ষ $PNQPTJUFύλʔϯ • ষ 0CTFSWFSύλʔϯ σβΠϯύλʔϯͷճؼ • ষ
• "CTUSBDU4FSWFSύλʔϯ • "EBQUFSύλʔϯ • #SJEHFύλʔϯ 2
࣍ • ষ $PNQPTJUFύλʔϯ • ষ 0CTFSWFSύλʔϯ σβΠϯύλʔϯͷճؼ • ষ
• "CTUSBDU4FSWFSύλʔϯ • "EBQUFSύλʔϯ • #SJEHFύλʔϯ 3
ষ $PNQPTJUFύλʔϯ • オブジェクトを管理するクラスが 管理対象のオブジェクトの集合体としてふるまうパターン • 実際は1:nの関係にあるものを1:1の関係であるように⾒せられる • 理解が簡単 •
コーディングが楽 • 保守が楽 4
$PNQPTJUFύλʔϯͷྫ 5 protocol Shape { func draw() } struct CompositeShape:
Shape { let shapes: [Shape] func draw() { shapes.forEach { $0.draw() } } } Composite⾃体がShapeに準拠 CompositeはShapeを保持 Shapeと同じインタフェースを使って 複数のShapeをDraw
·ͱΊ • Compositeパターンはほとんどコードに変更を与えずに導⼊できる • 1:nの関係を1:1の関係のように⾒せかけることによって,コードを簡単に出来る • 管理対称のオブジェクトを同⼀と⾒なせない場合にこのパターンは⽤いるべき ではない • 例)従業員のリストから今⽇が給料⽇の従業員を取り出す
6
࣍ • ষ $PNQPTJUFύλʔϯ • ষ 0CTFSWFSύλʔϯ σβΠϯύλʔϯͷճؼ • ষ
• "CTUSBDU4FSWFSύλʔϯ • "EBQUFSύλʔϯ • #SJEHFύλʔϯ 7
ষ 0CTFSWFSύλʔϯ σβΠϯύλʔϯͷճؼ • リファクタリングの過程によってデザインパターンに回帰する • デザインパターンは天下り的に与えられない • 下記のコードがリファクタリングの結果,Observerパターンに回帰します. 8
OSから与えられる時間情報clockを使って アプリケーション上に時間を表⽰するコード
ষ αϯϓϧίʔυͷ • Whileによって無駄なループが発⽣している • CPUを必要以上に専有してしまっている • 時間を取得するのはClockが保持する時間が更新されたタイミングのみでいいはず 9 OSから与えられる時間情報clockを使って
アプリケーション上に時間を表⽰するコード
ষ αϯϓϧίʔυͷվળᶃ • TimeSource(Clockの抽象型)の変更を TimeSinkクラスに通知する. • 2者間の通知には,ClockDriverを介して⾏う • 時間が変更したときのみ,TimeSinkに時間が流れる 10
ষ αϯϓϧίʔυͷվળᶃ • TimeSource(Clockの抽象型)の変更を TimeSinkクラスに通知する. • 2者間の通知には,ClockDriverを介して⾏う • 時間が変更したときのみ,TimeSinkに時間が流れる 11
問題点 TimeSourceがClockDriverに依存 誰でもTimeSourceを使えるようにしたい
ষ αϯϓϧίʔυͷվળᶄ • ClockObserverを作成 • ClockDriverはClockObserverに準拠 • TimeObserverはClockObserverに依存するように 変更 12
ষ αϯϓϧίʔυͷվળᶄ • ClockObserverを作成 • ClockDriverはClockObserverに準拠 • TimeObserverはClockObserverに依存するように 変更 13
問題点 複数の時計を表⽰するような場合 複数のsinkを許容する必要がある 問題点 update(:Time)とsetTime(:Time) は同じ事をしている ClockDriverは必要無い
ষ αϯϓϧίʔυͷվળᶅ • Driverを消去 • TimeSourceが複数のObserverを管理する ように変更 14
ষ αϯϓϧίʔυͷվળᶅ • Driverを消去 • TimeSourceが複数のObserverを管理する ように変更 15 問題点 TimeSourceに準拠するクラス全てが
このメソッドを実装しなくてはいけない
ষ αϯϓϧίʔυͷվળᶅ • Baseクラスを作り, Observerに関する処理は 親クラスに詰め込んだ 16
ষ αϯϓϧίʔυͷվળᶅ • Baseクラスを作り, Observerに関する処理は 親クラスに詰め込んだ 17 問題点 名前からObserverを管理することを 察せられない
ষ αϯϓϧίʔυͷվળᶆ • Subjectという名前を使⽤ • Subjectの名前に合うように 値の取得⽅向を逆転させた 18
ষ αϯϓϧίʔυͷվળᶆ • Subjectという名前を使⽤ • Subjectの名前に合うように 値の取得⽅向を逆転させた 19 Observerパターンに なりました
0CTFSWFSύλʔϯɼԿ͕خ͍͠ͷ͔ • OCPに準拠する • 監視対象のオブジェクトを⼀切修正せずに,Observerのオブジェクトを追加できる • LSPに準拠する • 例)ClockはSubjectと置換可能 •
DIPに準拠する • 今回の例ではSubjectが具体型であったが, Subjectが単体でインスタンス化することはないので論理的には抽象型 20
࣍ • ষ $PNQPTJUFύλʔϯ • ষ 0CTFSWFSύλʔϯ σβΠϯύλʔϯͷճؼ • ষ
• "CTUSBDU4FSWFSύλʔϯ • "EBQUFSύλʔϯ • #SJEHFύλʔϯ 21
ষ "CTUSBDU4FSWFSύλʔϯͷྫ • 下記のような設計について考える • Swtichが物理的なスイッチ状態をポーリング • SwitchがLightに依存しており,状態をLightに伝える 22 Switch
Light + turnOn + turnOff
ষ "CTUSBDU4FSWFSύλʔϯͷྫ • 下記のような設計について考える • Swtichが物理的なスイッチ状態をポーリング • SwitchがLightに依存しており,状態をLightに伝える 23 Switch
Light + turnOn + turnOff DIP違反 具体的な型に依存している OCP違反 Switchが必要な場合にはLightも連れていかないと ダメ
ষ "CTUSBDU4FSWFSύλʔϯͷద༻ • SwitchはSwitchによって制御可能なSwitchableに依存 • SwitchableはインタフェースなのでDIPに準拠 • 同時にOCPにも準拠 24 Switch
<interface> Switchable + turnOn + turnOff Light + turnOn + turnOff
ষ "CTUSBDU4FSWFSύλʔϯͷద༻ • SwitchはSwitchによって制御可能なSwitchableに依存 • SwitchableはインタフェースなのでDIPに準拠 • 同時にOCPにも準拠 25 Switch
<interface> Switchable + turnOn + turnOff Light + turnOn + turnOff インタフェースはクライアントに属する Lightが継承しているからといってLightInterfaceと いった名前にしない. Switch(クライアント)が使うのでSwitchable.
࣍ • ষ $PNQPTJUFύλʔϯ • ষ 0CTFSWFSύλʔϯ σβΠϯύλʔϯͷճؼ • ষ
• "CTUSBDU4FSWFSύλʔϯ • "EBQUFSύλʔϯ • #SJEHFύλʔϯ 26
ষ "EBQUFSύλʔϯͷྫ • 下記のような設計について考える • Swtichが物理的なスイッチ状態をポーリング • SwitchがLightに依存しており,状態をLightに伝える 27 Switch
Light + turnOn + turnOff もしLightがサードパーティが作ったもので Switchableに準拠させられない場合は....?
ষ "EBQUFSύλʔϯͷదԠ • 間に⼀枚挟んで,Interfaceの変換のような事を⾏う • このように,Adapter⾃⾝がAdapte対称を継承することをクラス形式のAdapterパターンという 28 Switch <interface> Switchable
+ turnOn + turnOff LightAdapter + turnOn + turnOff Light + turnOn + turnOff
ষ "EBQUFSύλʔϯͷదԠ • 間に⼀枚挟んで,Interfaceの変換のような事を⾏う • このように,Adapter⾃⾝がAdapte対称を継承することをクラス形式のAdapterパターンという 29 Switch <interface> Switchable
+ turnOn + turnOff LightAdapter + turnOn + turnOff Light + hogehoge + fugafuga ここは何でも良い
࣍ • ষ $PNQPTJUFύλʔϯ • ষ 0CTFSWFSύλʔϯ σβΠϯύλʔϯͷճؼ • ষ
• "CTUSBDU4FSWFSύλʔϯ • "EBQUFSύλʔϯ • #SJEHFύλʔϯ 30
ষ #SJEHFύλʔϯͷྫ • 下記のようなモデムを表現した実装がある • このモデルにdialとhangupが必要ないDelicated Modemが追加されることとなった • すでにこのシステムは多くの顧客に使われており,インタフェースを分離できない 31
ষ #SJEHFύλʔϯͷྫ • 問題の根底が下記のような依存関係になった,と捉えると Bridgeパターンが適応出来る 32
ষ #SJEHFύλʔϯͷదԠ • 各もモデムの振る舞いは ModelImlpletetionに譲渡 • ストラテジーパターン? • Delicated Modemの場合は
dialとhangupだけを実装 33
ষ ·ͱΊ • 仕様変更の要求は必ず起こる上に時間は有限 • ⼗分な分析は常に出来ないので,コストと利益とのバランスが取れるように設計していく 必要がある • Adapterパターンを使った⽅法 •
実装がシンプル • 全ての依存関係が正しい⽅向に向くようになっている • Bridhgeパターン • 構造を完璧に分離する必要がある • 拡張性は⾼い 34
Ҿ༻ • ロバート・C・マーチンほか.アジャイルソフトウェア開発の奥義 第 2版 オブジェクト指向開発の神髄と匠の技. SBクリエイティブ, 2008 35