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
64
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
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 Technology
See All in Technology
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership, regardless of position
madoxten
19
9.6k
Introduction to OpenSearch Project - Search Engineering Tech Talk 2025 Winter
tkykenmt
2
230
JAWS FESTA 2024「バスロケ」GPS×サーバーレスの開発と運用の舞台裏/jawsfesta2024-bus-gps-serverless
ma2shita
3
370
貧民的プログラミングのすすめ
kakehashi
PRO
1
150
株式会社Awarefy(アウェアファイ)会社説明資料 / Awarefy-Company-Deck
awarefy
3
12k
LINE NEWSにおけるバックエンド開発
lycorptech_jp
PRO
0
390
サバイバルモード下でのエンジニアリングマネジメント
konifar
22
7.4k
LayerXにおけるAI活用事例とその裏側(2025年2月) バクラクの目指す “業務の自動運転” の例 / layerx-ai-deim2025
yuya4
4
830
“常に進化する”開発現場へ! SHIFTが語るアジャイルQAの未来/20250306 Yuma Murase
shift_evolve
0
110
遷移の高速化 ヤフートップの試行錯誤
narirou
6
2k
目標と時間軸 〜ベイビーステップでケイパビリティを高めよう〜
kakehashi
PRO
8
1k
どうすると生き残れないのか/how-not-to-survive
hanhan1978
1
100
Featured
See All Featured
Optimising Largest Contentful Paint
csswizardry
34
3.1k
Git: the NoSQL Database
bkeepers
PRO
428
65k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
A Tale of Four Properties
chriscoyier
158
23k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.5k
A Philosophy of Restraint
colly
203
16k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
660
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
193
16k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
134
33k
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