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
Naoki Kitora
September 29, 2025
Programming
120
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
リファクタリング入門 〜日常的にコードを育てるための第一歩〜
Naoki Kitora
September 29, 2025
Other Decks in Programming
See All in Programming
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
400
クラウドゲーミングのパフォーマンス最適化に挑む / Cloud Gaming Performance Tuning
vivion
0
310
AI時代のTerminal環境を UNIX哲学で設計・運用する
yasunori0418
1
330
高橋メソッドでCVE解説シリーズ 〜CVE-2026-112816〜
hakkadaikon
0
150
LLM 101
dalinaum
0
430
最近”作らせてる” ローカルAIアプリの話
akit37
0
530
[DroidKnights 2026] Workflow AX: From Auto-Documented Policies to E2E Testing
raeminkang
0
170
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
220
Inertia Rails: The One-Person Framework with React & Friends
skryukov
0
200
エージェントを使い続けるためのメタワーク / Meta-work for keeping using the agent
rkaga
6
2.1k
graphql-ruby を Spinel で速くしようとした話
mtsmfm
0
140
SFCで実現する病院・医療システムの動的組み立て式UI
koukimiura
1
150
Featured
See All Featured
KATA
mclloyd
PRO
35
16k
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.2k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.7k
Discover your Explorer Soul
emna__ayadi
2
1.3k
How to Ace a Technical Interview
jacobian
280
24k
Mind Mapping
helmedeiros
1
420
The Cost Of JavaScript in 2023
addyosmani
55
10k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.4k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Optimising Largest Contentful Paint
csswizardry
37
4k
How to Talk to Developers About Accessibility
jct
2
600
Embracing the Ebb and Flow
colly
88
5.2k
Transcript
リファクタリング入門 〜日常的にコードを育てるため 第一歩〜 関ジャバ 2025年 9月度 2025-09-26 木虎 直樹
自己紹介 木虎 直樹 株式会社ティアライン CTO アプリケーションエンジニア (Java, Python, Scala, JavaScript,
etc.) インフラエンジニア (OS, ミドルウェア、ネットワーク、クラウド) プロジェクトマネージャ (アプリケーション開発、AI 開発、etc.)
DISCLAIMER リテラル値をハードコーディングしている箇所が多数ありますが、紙面 都合上やむなく そ ようにしておりますことをあらかじめご了承ください。
Agenda • リファクタリングと • なぜリファクタリングをする か • いつリファクタリングをする か •
どこをリファクタリングする か (リファクタリング事例) • リファクタリング 進め方
リファクタリングと リファクタリング (名詞): 外部から見たとき 振る舞いを保ちつつ、理解や修正が簡単になるように、ソフトウェア 内部構造を変化させること リファクタリングする (動詞): 一連 リファクタリングを適用して、外部から見た振る舞い
変更なしに、ソフトウェアを 再構築すること ソフトウェア設計を改善 コードを洗練
なぜリファクタリングをする か • コードが理解しやすく修正が簡単になるためバグ 入り込む余地が最小化 ◦ 生産性向上 ◦ コード 読まれる時間
ほうが長い ▪ パフォーマンスよりもまず 可読性 • 最初からすべてを見通して詳細に設計する 不可能 ◦ 実装 過程で気づく ◦ 使ってから気づく ◦ 運用してから気づく • ソフトウェア 成長とともにエントロピーが増大 ◦ 追加開発により当初考えていなかったことが発生 ◦ 車輪 再発明 ◦ 具体性 高い (抽象度 低い、汎用性 低い ) 実装
ハードウェアで なくソフトウェアだからしやすい
いつリファクタリングをする か • 変更要求に対応する準備 ◦ 変更を容易にするため • バグ修正や調査 タイミング ◦
コード修正 前に何をしている か理解するため • 理解 できるが、良くない書き方を見つけたとき ◦ ゴミ拾い • 一通り 実装が完了し、コードレビューを依頼する前 ◦ 推敲
どこをリファクタリングする か (リファクタリング事例) コード 不吉な匂い (Code Smells) する箇所 • 謎な名前
(Mysterious Name) • 重複したコード (Duplicated Code) • 長い関数 (Long Function) • 巨大なクラス (Large Class) • ネストが深い (※) • etc. ※ Martin Fowler 著書リファクタリング「第 3章 コード 不吉な匂い」に 挙がっていない
謎な名前 (Mysterious Name) なぜダメ? 名付け 設計 • 適切な名前がつけられるということ 、そ クラスやメソッド、変数
役割が明確か つ適切であるということ • 適切な名前がつけられていれ コードが読みやすい ◦ メソッド 実装を読まなくても処理が想像できる ◦ コードを詳細に追っていかなくても変数に何が入っているか想像できる
謎な名前 (Mysterious Name) public class InvoiceService { public double cal(double
a, double b) { return a * b * 1.1; } } public class InvoiceService { private static final double TAX_RATE = 0.1; public double calculateTotalPrice(double unitPrice, double quantity) { double subtotal = unitPrice * quantity; return subtotal * (1 + TAX_RATE); } }
謎な名前 (Mysterious Name) 一種 ありがちなダメな名前 ***Flag (e.g. updateFlag) true (or
false) 場合にどういう意味な か直感的にわからない 更新するべきかどうかを保持 : shouldUpdate 更新したというステータスを保持 : updated 更新しても良いかどうかを保持 : canUpdate ***Flag 副作用 if (updateFlag == true) { // 比較したくなる }
謎な名前 (Mysterious Name) 一種 これまでに見たも でも特に印象に残っているも latitude, mild 緯度 わかるけどマイルドって何
? 緯度 次に来る 普通に考えたら経度 (longitude) で ? 経度、ケイド、けいど、けいど ? けいど?! ……
軽度!!
重複したコード (Duplicated Code) なぜダメ? 似ているけど違う部分 ないか読まなけれ ならない 修正 際 もれなく重複箇所を洗い出し、すべて修正しなけれ
ならない コピペでし し 量産される……
重複したコード (Duplicated Code) public class DiscountCalculator { public double calculateForRegularCustomer(double
price) { double discounted = price * 0.9; return discounted < 100 ? 100 : discounted; } public double calculateForPremiumCustomer(double price) { double discounted = price * 0.8; return discounted < 100 ? 100 : discounted; } }
重複したコード (Duplicated Code) public class DiscountCalculator { public double calculateForRegularCustomer(double
price) { return applyMinimumPrice(price * 0.9); } public double calculateForPremiumCustomer(double price) { return applyMinimumPrice(price * 0.8); } private double applyMinimumPrice(double discounted) { return discounted < 100 ? 100 : discounted; } }
重複したコード (Duplicated Code) で最近見た例 • コピペで量産された 20個くらい 関数 (Python です)
◦ 関数 役割ごとに 10個から 20個存在する ▪ ここでいう関数 役割と データ読み込み、データ変換、データ書き出しなど ◦ 大体 コピペだが、長年 製品開発で一部だけ改良している亜種が存在 • 対応 ◦ 方針を検討 ▪ 関数をクラス メソッドとし、共通部分 抽象クラスに引き上げる ◦ 処理を分割 (メソッド/関数抽出) ◦ 抽象クラスを定義 ◦ 重複部分を抽象クラスに引き上げ ◦ 各関数を具象クラス・メソッドに変換
長い関数 (Long Function) なぜダメ? • 大抵 場合、複数 処理が 1つ 関数・メソッドに詰め込まれていて全体
見通し が悪く可読性が低い ◦ 概要 掴みづらさを補足するためにコメントが付与されていることも多い • それぞれ 処理を個別にテストできない
長い関数 (Long Function) public class OrderService { public double calculateFinalPrice(Order
order) { double subtotal = 0; for (OrderItem item : order.getItems()) { subtotal += item.getUnitPrice() * item.getQuantity(); } // 割引の適用 double discount = 0; if (order.getCustomer().isPremium()) { discount = subtotal * 0.1; } else if (subtotal > 10000) { discount = subtotal * 0.05; } // 税金の計算 double tax = (subtotal - discount) * 0.1; // 配送料の計算 double shipping = subtotal > 5000 ? 0 : 500; return subtotal - discount + tax + shipping; } } 変数 再代入も起こりがち
長い関数 (Long Function) public class OrderService { private static final
double TAX_RATE = 0.1; public double calculateFinalPrice(Order order) { double subtotal = calculateSubtotal(order); double discount = calculateDiscount(order, subtotal); double tax = calculateTax(subtotal, discount); double shipping = calculateShipping(subtotal); return subtotal - discount + tax + shipping; } private double calculateSubtotal(Order order) { return order.getItems() .stream() .mapToDouble(item -> item.getUnitPrice() * item.getQuantity()) .sum(); } // 以下略 }
ネストが深い なぜダメ? • 言うまでもなく読みづらい
ネストが深い public class UserService { public boolean canAccessResource(User user, Resource
resource) { if (user != null) { if (user.isActive()) { if (resource != null) { if (resource.isPublic() || user.hasPermission(resource)) { return true; } else { return false; } } else { return false; } } else { return false; } } else { return false; } } }
ネストが深い public class UserService { public boolean canAccessResource(User user, Resource
resource) { if (user == null) return false; if (!user.isActive()) return false; if (resource == null) return false; if (resource.isPublic()) return true; return user.hasPermission(resource); } }
ネストが深いわけで ないけど…… if (updateFlag) { // なんか処理する // まだ処理してる //
まだまだ続くよ // その後も続く何十行もの処理 // …… // …… // …… // …… // …… // …… // 100行以上処理が続いてたんじゃないかなぁ } else { throw new RuntimeException("updateFlag が false なのは不正") } 例外処理 先が原則
リファクタリング 進め方 • まず テスト ◦ Unit テストがなけれ テストを作る ▪
あるべき仕様がわからない場合 To Be で なく As Is で良い で作る • 小さな変更と変更 たび テスト ◦ 壊れたときにすぐわかる ▪ デバッグ範囲が限定される ◦ 成功したらコミット ▪ 壊れてもすぐに戻せる
忘れて ならないこと • リファクタリング 直接的にユーザに価値を届けるも で ない • 修正 必要がない場合
リファクタリング不要
まとめ • リファクタリングと • なぜリファクタリングをする か • いつリファクタリングをする か •
どこをリファクタリングする か (リファクタリング事例) • リファクタリング 進め方
参考書籍