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
Visitorパターン
Search
k-kohey
October 28, 2019
Programming
0
190
Visitorパターン
k-kohey
October 28, 2019
Tweet
Share
More Decks by k-kohey
See All by k-kohey
ゲームボーイアドバンスでSwiftを動かそう
k_koheyi
0
1.1k
Swift Package Mangerのバグを直した話
k_koheyi
2
1.5k
swift-async-algorithms...? へえ…面白そうじゃん…?
k_koheyi
3
1.6k
[社内勉強会]Parchment-swiftの実装説明
k_koheyi
0
130
[社内勉強会]Combineの説明
k_koheyi
0
36
あるインスタンスの取る値が 何パターンあるか数えてみるンゴ!
k_koheyi
1
170
Tuistを用いた Xcode Project管理の紹介
k_koheyi
0
210
SwiftでわかるSOLID原則 iOSDC 2020
k_koheyi
3
2.8k
Application Design 勉強会23-25章
k_koheyi
0
77
Other Decks in Programming
See All in Programming
Cursor AI Agentと伴走する アプリケーションの高速リプレイス
daisuketakeda
1
130
アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介
andpad
0
270
明示と暗黙 ー PHPとGoの インターフェイスの違いを知る
shimabox
2
380
Railsアプリケーションと パフォーマンスチューニング ー 秒間5万リクエストの モバイルオーダーシステムを支える事例 ー Rubyセミナー 大阪
falcon8823
4
1k
Cline指示通りに動かない? AI小説エージェントで学ぶ指示書の書き方と自動アップデートの仕組み
kamomeashizawa
1
580
関数型まつり2025登壇資料「関数プログラミングと再帰」
taisontsukada
2
850
A2A プロトコルを試してみる
azukiazusa1
2
1.2k
Julia という言語について (FP in Julia « SIDE: F ») for 関数型まつり2025
antimon2
3
980
AIプログラマーDevinは PHPerの夢を見るか?
shinyasaita
1
170
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
300
5つのアンチパターンから学ぶLT設計
narihara
1
120
第9回 情シス転職ミートアップ 株式会社IVRy(アイブリー)の紹介
ivry_presentationmaterials
1
250
Featured
See All Featured
Practical Orchestrator
shlominoach
188
11k
It's Worth the Effort
3n
185
28k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Docker and Python
trallard
44
3.4k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.8k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.7k
KATA
mclloyd
30
14k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.3k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
Transcript
"QQMJDBUJPO%FTJHO ษڧձ ষ ஜେֶ ใϝσΟΞֶྨ ޱ ߤฏ 1
࣍ • ষ 7JTJUPSύλʔϯ • 7JTJUPSύλʔϯ • "DZDMJD7JTJUPSύλʔϯ • %FDPSBUPSύλʔϯ
• &YUFOTJPO 0CKFDUύλʔϯ 2 ط ଘ ͷ ֊ ߏ ʹ ख Λ Ճ ͑ ͣ ʹ ৽ ͠ ͍ ϝ ι ỽ υ Λ Ճ ͢ Δ ͨ Ί ʹ
എܠ • 下記のようなモデムを制御するためのクラス群がある • Hays,Zoom,およびErnieは全てべつのハードウェアを制御する 3 <interface> Modem Hays Zoom
Ernie
എܠ • 下記のようなモデムを制御するためのクラス群がある • Hays,Zoom,およびErnieは全てべつのハードウェアを制御する 4 <interface> Modem Hays Zoom
Ernie ModemとUnixを接続する configureForUnixを追加して
എܠ • Modemに対応OSが増える毎にModemにインタフェースが増える ⇢ その都度,すべてのモデムソフトウェアを再配布するハメになる 5 <interface> Modem + configureForUnix
+ configureForLinux + configureForWindows …. Hays Zoom Ernie そのモデルが 追加されたOSを サポートするかに 関わらず 必ず変更を要する
ղܾ͍ͨ͠ • ModemインタフェースにconfigureForUnixメソッドを追加せずに Unix対応をする ⇢ 既存の階層構造に⼿を⼊れずに新しいメソッドを追加する 6 <interface> Modem Hays
Zoom Ernie
7JTJUPSύλʔϯͷ࣮ cΫϥεਤ • OS依存の処理をModemVisitorに委託する • Modem::acceptからModemVisitorの処理を実⾏ 7 <interface> Modem +
accept(ModemVisitor) Hays Zoom Ernie UnixModem Configurator <interface> ModemVisitor + visit(Hayes) + visit(Zoom) + visit(Ernie)
7JTJUPSύλʔϯͷ࣮ cίʔυ • OS依存の処理をModemVisitorに委託する • Modem::acceptからModemVisitorの処理を実⾏ 8 <interface> Modem +
accept(ModemVisitor) Hays Zoom Ernie UnixModem Configurator <interface> ModemVisitor + visit(Hayes) + visit(Zoom) + visit(Ernie)
7JTJUPSύλʔϯͷ cยଆͷมߋ͕͏ยଆʹൖ 9 <interface> Modem + accept(ModemVisitor) Hays Zoom Ernie
UnixModem Configurator <interface> ModemVisitor + visit(Hayes) + visit(Zoom) + visit(Ernie) Visitする側 Visitされる側
7JTJUPSύλʔϯͷc7JTJUPSʹੜΫϥεΛੜ͢ͷ͕େม • HogeModemを追加する場合は? • Modemを継承したHogeModemクラスを追加 • ModemVisitorにvisit(:HogeModem)メソッドを追加 • ModemVisitorを継承しているすべての派⽣クラスにvisit(:HogeModem)を追加 •
UnixModemConfiguration以外にもLinuxModemConfigurationやWindowsModemConfigurationも 考えられる • 実際に必要とならないところにもvisit(:HogeModem)は実装しなくてはいけない ModemVisitorに派⽣クラスがあると(or増やそうとすると) 変更が多くて⼤変
"DZDMJD7JTJUPSύλʔϯ cΫϥεਤ • ⾮循環のVisitorパターン,Acyclic Visitorを使えば問題は解決する 11 <interface> Modem + accept(ModemVisitor)
Hays Ernie Zoom <interface> Hays + visit(Hays) <interface> Zoom + visit(Hays) <interface> Ernie + visit(Hays) UnixModem Configuration <delegate> ModemVisitor
"DZDMJD7JTJUPSύλʔϯ cίʔυ • ⾮循環のVisitorパターン,Acyclic Visitorを使えば問題は解決する 12 <interface> Modem + accept(ModemVisitor)
Hays Ernie Zoom <interface> Hays + visit(Hays) <interface> Zoom + visit(Hays) <interface> Ernie + visit(Hays) UnixModem Configuration <delegate> ModemVisitor
"DZDMJD7JTJUPSύλʔϯ cྑ͍͜ͱ • ⾮循環のVisitorパターン,Acyclic Visitorを使えば問題は解決する 13 <interface> Modem + accept(ModemVisitor)
Hays Ernie Zoom <interface> Hays + visit(Hays) <interface> Zoom + visit(Hays) <interface> Ernie + visit(Hays) UnixModem Configuration <delegate> ModemVisitor Modemの派⽣クラスが増えても 変更が伝搬しない
7JTJUPSύλʔϯ·ͱΊ • 1つのデータ構造をいろいろと違った形で利⽤しなければいけないアプリ ケーションで便利 • データ構造とVisitorは無関係 • 既存のデータ構造を再構成したりせずに 新しいVisitorを追加したり変更したりできる •
既存のデータ構造に影響を与えずに,Visitorを配布出来る
%FDPSBUPSύλʔϯ • Visitorと同様なことを提供してくれるパターン!! <interface> Modem + dial Hays Zoom Ernie
%FDPSBUPSύλʔϯc ྫ • dialをするときにその⾳量ボリュームを制御したい • 下記のような実装はコピペの嵐を⽣んでしまう <interface> Modem + dial
Hays Zoom Ernie
%FDPSBUPSύλʔϯc ྫ • dialをするときにその⾳量ボリュームを制御したい • 新しいModemの派⽣クラスの作者はこのコードを知っていなくてはいけない <interface> Modem + dial
Hays Zoom Ernie
%FDPSBUPSύλʔϯ • ボリュームの変更を⾏うModemはLoudDialModemを使ってラップする <interface> Modem + dial Hays Zoom Ernie
LoudDialModem <delegate>
%FDPSBUPSύλʔϯ • ボリュームの変更を⾏うModemはLoudDialModemを使ってラップする <interface> Modem + dial Hays Zoom Ernie
LoudDialModem <delegate> システムの他の部分に影響を与えずに ⾳量を上げられる!
%FDPSBUPSύλʔϯ • ボリュームの変更を⾏うModemはLoudDialModemを使ってラップする <interface> Modem + dial Hays Zoom Ernie
LoudDialModem <delegate> 継承してるので Modemとして振る舞える
&YUFOTJPO0CKFDUύλʔϯ • Visitorと同様なことを提供してくれるパターン!! • 部品⼀覧を取り扱うアプリケーションを考える • 複合部品のAssembly • 単⼀部品のPiecePart •
Partの構成する部品をXMLで吐き出す機能を 追加したい • Partの中に処理を押し込むとSRP違反になる
&YUFOTJPO0CKFDUύλʔϯ • Visitorと同様なことを提供してくれるパターン!! • 部品⼀覧を取り扱うアプリケーションを考える
&YUFOTJPO0CKFDUύλʔϯ 基底クラスが Extensionを管理 所有している 派⽣クラスの情報を参照して XMLを作成 派⽣クラスから 基底クラスのExtension を参照し, XMLを取得できる
&YUFOTJPO0CKFDUύλʔϯ • Extensionを挿⼊したり,消去したりすることが出来るのが特徴 • 柔軟性が⼤きい • 実際にこれが必要になる機会は少ない
݁ • Visitor系のパターンは既存のクラスに変更を加えずに, クラス階層構造の振る舞いを変更できる • OCPを維持する⼿助けとなる • 異なる機能がクラス内に分散するのを防ぐ • CCPを維持する⼿助けとなる
• SRP,LSP,DIPにも適合 • Visitorパターンで解決出来る問題はもっとシンプルな⽅法で解決出来る 可能性があるから懐疑的な態度を持とう
Ҿ༻ • ロバート・C・マーチンほか.アジャイルソフトウェア開発の奥義 第 2版 オブジェクト指向開発の神髄と匠の技. SBクリエイティブ, 2008 26