Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
オブジェクト指向による変更容易性の高いソフトウェア設計技法
Search
Ryosuke Fujii
December 06, 2021
Technology
46
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
オブジェクト指向による変更容易性の高いソフトウェア設計技法
Ryosuke Fujii
December 06, 2021
Other Decks in Technology
See All in Technology
Local CI × GitHub Actions
gogutan
3
230
事業成長とデータ活用を止めないためのマネジメントへ挑戦
hiracky16
0
400
Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
1
780
今さら理解するウェブフォントver.2026
takanorip
3
910
大型犬好きによるPugの紹介
yamanoku
1
160
フロントエンドカンファレンス関西2026 - 速すぎるUIに、待ち時間を
teamlab
PRO
0
190
エンタメ企業のM&Aを支えるデータ基盤 ― 統合から店舗のリアルタイム分析まで / Data Engineering Summit 2026
genda
0
200
Webの常識が通じないHTMLメールのダークモード
teamlab
PRO
0
140
Persisting Massive Data with Rails ~Designing for 60 billion rows, and fighting the bottlenecks~ Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
0
740
オントロジーって 結局なにもの? AI エージェントに「意味」を渡す知識設計の話
greenmidori
0
230
WasmをRustにする
sansantech
PRO
0
280
データエンジニアの次の戦場は "プロセスエンジニアリング"
sansantech
PRO
1
110
Featured
See All Featured
Accessibility Awareness
sabderemane
1
250
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.9k
WENDY [Excerpt]
tessaabrams
14
40k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
630
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
360
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
Automating Front-end Workflow
addyosmani
1369
210k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
5.3k
Transcript
オブジェクト指向による 変更容易性の高い ソフトウェア設計技法 Presenter Fujii Ryosuke twitter @fujii_rrr
良いコードとは • 良いコードは、正しく動作することに加えて「変更がかんたん」である • 変更がかんたんとは ◦ 見通しが良い ▪ 変更箇所の特定がかんたんにできる ▪
変更による影響範囲をかんたんに特定できる ◦ 合理的である ▪ 要件の変更が小さければ、コードの変更も相応して小さい ◦ 再利用性 ▪ 既存のコードはかんたんに 再利用できる
変更がむずかしい例 • あるクラスを少し修正したなのに、他のクラスのテストコードが大量に落ちる • クラスが1万行あって一体何をしているのか、あるコードを変更した時にどういう影 響がでるのかわからない • パフォーマンス目的でDBのスキーマを変えるだけなのに、ビジネスロジックやUIロ ジックも変更しなければならない •
既存のコードを使うにはコピペするしかない
なぜ変更がかんたんである必要があるのか • システムの最終形である外部仕様が決まっていない • 変更の要求は絶えず発生する ◦ ビジネス要件の追加 ◦ バグ修正 ◦
UI改善 ◦ パフォーマンス改善による DBスキーマ・DBの変更 プロダクトの成長=事業の成長である我々にとって 「変更がかんたんである」ことが事業成長の鍵を握る
単一責任にクラスを分割する • 人間は複雑で大きな問題をそのまま解決することはできない ◦ 様々な関心ごとが絡み合い複雑で大きな問題となる ▪ レイアウトしたい ▪ 業務ロジックを組み立てたい ▪
データを加工したい ▪ 計算したい ▪ 通信したい ▪ 永続化したい • 関心の分離 ◦ 解決すべき複雑で大きな問題を単純で小さな問題に分解する ◦ 単純で小さな問題を個別に解決する=部品(モジュール) ◦ 部品(モジュール)を組み合わせて、複雑で大きな問題を解決する。
単一責任にクラスを分割する • 解決すべき問題領域を「責務」「責任」と呼ぶ • クラスが「単一責任」を持つように設計する • なぜ「単一責任」にすべきなのか ◦ 責任を複数持つ場合、再利用性が低く、壊れやすい ◦
1つの目的に関することだけを行う=高凝縮 利用する側 モジュールA 利用される側 モジュール 問題X 問題Y 利用する モジュールB
複数責任のクラスを見つける方法 • modeみたいな区分でクラス内の振る舞いを制御している • インスタンス変数を使用していないメソッドがある • クラスを一文で説明してみて、「または」が入る場合、複数の責務を持っている可能性がある
依存とは • モジュールAがBについて「知っている」時 AはBに依存していると言える • 「知っている」ことが多いほど密結合 • 例 ◦ OrderControllerクラスは
注文が注文明細を持っていることを知っている ▪ 不要な依存と言える ▪ 注文金額を計算するために注文 IDさえ 伝えれば良い
吉野家で牛丼を頼むために、調理法を知る必要はない 「牛丼並」を注文する 吉野家 (店員の名前は知らんけど) 吉野家の店員にメニュー名を使えれば注 文できる 顧客 外部から見た時に、 牛丼をどう作るかは ブラックボックス
注文受付
吉野家で牛丼を頼むために、調理法を知る必要はない 吉野家 まず冷凍された牛肉を6時間自然解凍した後に、、 しょうゆ・みりん・酒・砂糖を入れて1時間煮込んでください。 その後、ほかほかの白ごはんをどんぶり茶碗に盛って、 煮込んだ牛肉をその上にかけてください。 顧客 牛丼をどう作るかという手順を顧客が知っているため、 手順を変更する度に、顧客の注文の仕方を修正しなければならない
疎結合にする技法 • 具象ではなく抽象に依存する ◦ 内部詳細を隠蔽する ◦ インタフェースに依存する 日本の課税計算クラス アメリカの課税計算クラス カナダの課税計算クラス
注文金額クラス switch (国区分) case JP: 日本の課税計算クラス .calcTax case US: アメリカの課税計算クラス .calcTax case CAN: カナダの課税計算クラス .calcTax calcTax calcTax calcTax
疎結合にする技法 • 具象ではなく抽象に依存する ◦ 内部詳細を隠蔽する ◦ インタフェースに依存する 日本の課税計算クラス アメリカの課税計算クラス カナダの課税計算クラス
注文金額クラス なんからの課税計算をするクラス .calcTax 何らかの課税計算をするクラス calcTax
疎結合にする技法 • クリーンアーキテクチャにおけるUseCaseがRepositoryに依存する関係と同じ RemoteDataSource LocalDataSource UseCase なんからの方法で永続化するクラス .save 何らか方法で永続化するクラス save
ビジネスロジックから具体的な永続化の方法を分離する
費用対効果の高いテスト • テストコードの目的 ◦ バグを検知することはもちろんだが、 ◦ テストコードを書かない時に比べて、 開発の生産性を上げること • テストの種類
◦ ユニットテスト ▪ モジュールの動作試験 ◦ 結合テスト ▪ サブシステムレベルの動作確認 細かいテストはユニットテストで行う
プライベートメソッドはテストすべきか • 答え=すべきではない ◦ 冗長であるため ▪ パブリックメソッドがテスト内で、プライベートもテストされているはずである。プライベートメ ソッドをテストするのは冗長 ◦ 変更コストが高い
▪ プライベートメソッド=内部詳細はパブリックメソッドに比べて変わりやすい。 モジュールのインタフェースに対してテストを行う
副作用のあるオブジェクト呼び出しのテスト • クラス内に副作用のあるオブジェクト呼び出しがある場合、ユニットテストとしてどこまでテストすべき か ◦ 例) ▪ 注文作成クラスで通知オブジェクトを呼び出しているが、 ユニットテストとして通知テーブルにレコードが作成されたことまで確認する必要があるのか ◦
個人的には、モックを使って、「オブジェクトの呼び出しが適切に行われたこと」あるいは「戻り値の確認」をテストする だけで良いと考えている。 ▪ 理由 • テーブルにレコードを適切に作成することは、通知オブジェクトのユニットテストの範囲であり、アクショ ン作成クラスのテストではない。 • もしオブジェクトの呼び出し自体に問題があれば、結合テストで検知できる • 通知オブジェクトの内部処理変更時に、呼び出し側クラスのテストコードまで変更しなければならない。