VS Code Conference Japan 2022 - 2023
2023/01/21 nikkie 14:20-
このトークでは、書籍『リファクタリング』で紹介されたテクニックをVS Codeの操作と結び付けて理解するのを目的とします。
イベントサイト より
リファクタリングは、ソフトウェアの外部的な振る舞いを保ったままで、内部の構造を改善する作業を指します。
書籍サイト(リンク先)の「内容紹介」より
Martin Fowler著、「リファクタリングのガイドブック」(「内容紹介」より)
IMO:リファクタリングテクニックをたくさん載せた カタログ
Web版(英語) https://refactoring.com/catalog/
📘『リファクタリング』のテクニックのいくつかを
VS Codeの操作と結びつけて 理解する
VS CodeのUIは 英語 で紹介
本発表のコード例は Python (後述)
「リファクタリング」のとらえ方(後述)
Pythonの詳細には立ち入りません
📘『リファクタリング』ではJavaScript
「リファクタリングは異なる言語でもほぼ同じような形になります。」(📘の「はじめに」「JavaScriptによる例」)
異なる=「小さい!」かもしれません
このトークの「リファクタリング」は、開発中に絶えずやる、コードの構造の小さい改善 を指しています
数日〜数週かける規模のリファクタリングは想定していません(テクニックは適用できるかも)
XPのプラクティスの1つ テスト駆動開発
「動作するきれいなコード」を目指す(Red-Green-Refactoring)
まず動作させ(Green)、次にきれいにする(リファクタリング)。この 小さいサイクルを何回も 繰り返す
トークの認識合わせ✅
主張:リファクタリングテクニックをエディタと結び付けよう
カタログ:VS Codeでリファクタリング(別目次)
トークの認識合わせ
主張:リファクタリングテクニックをエディタと結び付けよう
カタログ:VS Codeでリファクタリング(別目次)
個々のテクニックは 名詞のリファクタリング
※これをエディタと結び付けようと共有していきます
外部から見たときの振る舞いを保ちつつ、理解や修正が簡単になるように、ソフトウェアの内部構造を変化させること
📘『リファクタリング』第2章の中の「リファクタリングの定義」
変えるのは構造だけ
振る舞いは変えない
開発者がコードを理解しやすく・変更しやすくするために構造を変える
名詞のリファクタリング 複数を適用 して構造を変えること
1つ1つのテクニックは小さい。組合せて適用する
名詞のリファクタリングの手順は、📘『リファクタリング』6章以降で解説される
6章が基本のリファクタリングテクニック。基本を 組合せ たテクニックも存在する
俺は弱い! だから 正解に近づけていく (リファクタリングもその一環)
参考: Make It Work Make It Right Make It Fast
まず動かしてから正しくする順 (その後に速くするが来る)
リファクタリングを「知っている」の先「使える」状態になるには、
エディタの操作 として身体で覚えよう
VS Codeを操作 してリファクタリングテクニックを適用できる
サポートしているテクニックの範囲はエディタによって異なる
IntelliJ IDEAはもっと広くサポート
「どんなとき に使うのか」
「エディタでは どんな操作 になるのか」
📘『リファクタリング』から あるべき を紹介
結び付け ます
トークの認識合わせ
主張:リファクタリングテクニックをエディタと結び付けよう
カタログ:VS Codeでリファクタリング(別目次)
変数名の変更
関数名の変更
変数の抽出
関数の抽出
特性の移動に関する数テクニック
どんなとき に使うのか
VS Codeでは どんな操作 になるのか
変数名の変更
関数名の変更
変数の抽出
関数の抽出
特性の移動に関する数テクニック
cache invalidation and naming things (Phil Karlton)
ref: TwoHardThings
名前重要 (by Matz)だけれど、激ムズ
IMO:一発でいい命名ができないからこそ、 いい名前に気付いたらコードを更新 して理解しやすくしたい
適切な名前に気付いたとき
コードを明快にしたい(理解しやすい・変更しやすい)
「不可思議な名前」 (📘『リファクタリング』第3章)
「変数への参照をくまなく探し、それらをすべて変更する。」(📘『リファクタリング』第6章)
- a = height * width
+ area = height * width
関数宣言の変更 の非常に重要なユースケース
Webカタログ:https://refactoring.com/catalog/changeFunctionDeclaration.html
一度に全部置き換える手順だけでなく、 漸進的に置き換える 手順がある
Rename Symbol
F2 キー(これだけ!)
https://code.visualstudio.com/docs/editor/refactoring#_rename-symbol
検索や置換 でも変数名や関数名は変更できるが、確認も必要
Rename Symbolは VS Codeに全部任せられる (同じ名前でもスコープを考慮!)
# 面積の計算。a を area にrenameする
a = height * width
# 面積を計算する関数。calc を calc_area にrenameする
def calc(height, weight):
# スコープを考慮してrenameされる例
a = height * weight
return a
適切な名前 に気付いたとき
F2 (Rename Symbol)
クラス名・属性名・メソッド名の変更もRename Symbolできます
フィールド名の変更 (📘第9章・Webカタログ)
モジュール名(spam.py
)の変更はPython拡張がサポート
変数名の変更
関数名の変更
変数の抽出
関数の抽出
特性の移動に関する数テクニック
初版では「説明用変数の導入」と呼ばれていた
Webカタログ:https://refactoring.com/catalog/extractVariable.html
式を説明するコメント を見つけた・書きたいとき
「コメントを書かなくとも内容がわかるようなコードを目指す」(📘『リファクタリング』第3章)
式を選択
Extract variable
Pythonの場合はPython拡張が提供
https://code.visualstudio.com/docs/python/editing#_extract-variable
VS Codeによって new_var
が抽出されるので、renameする
# base_price = order.quantity * order.item_price のように抽出する例
def price(order):
# price = base price - quantity discount + shipping
return (
order.quantity * order.item_price
- max(0, order.quantity - 500) * order.item_price * 0.05
+ min(order.quantity * order.item_price * 0.1, 100)
)
「変数の抽出」を繰り返すと、この例のコメントは不要になります
📘『リファクタリング』はエディタのサポートを受けない手順
式をコピーして変数を導入 ➡ 式を変数で置き換え
IMO:エディタの機能を使うことで 楽 ができる(常中しやすい)
式を説明するコメント がある・必要があると思われるとき
コードを選択して Extract variable
変数名の変更
関数名の変更
変数の抽出
関数の抽出
特性の移動に関する数テクニック
メソッドの抽出も含む(関数、メソッド、同じ意味)
Webカタログ:https://refactoring.com/catalog/extractFunction.html
処理の一部が コメントで説明されている とき
「長い関数」 (📘『リファクタリング』第3章)
コードの 自己文書化 (意図と実装を分離して、理解しやすく)
処理を選択
Extract method
Pythonの場合はPython拡張が提供
https://code.visualstudio.com/docs/python/editing#_extract-method
VS Codeによって new_func
が抽出されるので、renameする
# print detailsというコメントで説明された処理を関数に抽出する例
def print_owing(invoice):
print_banner()
outstanding = calculate_outstanding(invoice)
# print details (<- 「関数を抽出」すると、このコメントは不要になる)
print(f"name: {invoice.customer}")
print(f"amount: {outstanding}")
📘『リファクタリング』では まず は関数内関数(入れ子)として抽出する
渡す必要がある引数を1つずつ調整していって、最後に外側のスコープに移す
IMO:エディタのサポートで楽をしたいが、一足飛びだと嬉しくない場面もあり、この手順が必要になることも
def print_owing(invoice):
print_banner()
outstanding = calculate_outstanding(invoice)
print_details()
# まずは抽出だけ実施し、その後引数を調整します(関数宣言の変更)。最後に関数スコープの外へ
def print_details():
print(f"name: {invoice.customer}")
print(f"amount: {outstanding}")
長い関数で 一部を説明するコメント があるとき
コードを選択して Extract method
何度も登場する同じ式(重複は変更を難しくする🥺)
「重複したコード」(📘『リファクタリング』第3章)
重複した式を関数に抽出し、それで置き換えることで重複コードをなくす
変数名の変更
関数名の変更
変数の抽出
関数の抽出
特性の移動 に関する数テクニック
📘『リファクタリング』第8章
文・フィールド・関数を 移動 するリファクタリングテクニックを紹介
関連する要素をまとめる
一発で正解の関連を見つけることもまた難しい🥺
関連についての理解が深まったら、移動してまとめ方を更新 する
行をまとめて移動もできて便利
行を動かしただけで「特性の移動」が完了することは少ない
移動先の文脈に位置づける(引数の追加・編集が必要)
IMO:リファクタリングの 端緒 として、簡単にできる操作という点がオススメ
深まった理解に基づき、関連する要素の まとめ方を変える とき
⌥↑ や ⌥↓ が最初の操作
変数名の変更➡️ F2 (Rename Symbol)
関数名の変更➡️(同上)
変数の抽出➡️ Extract variable
関数の抽出➡️ Extract method
特性の移動に関する数テクニック➡️ ⌥↑ ⌥↓ で始めよう
振る舞いを変えずに構造を変えるのがリファクタリング
テストコードがあると、 振る舞いを変えてしまったことに気付ける
『テスト駆動開発』第25章の言葉
「リファクタリングで振る舞いを変えているんじゃないか」という不安がなくなった
都度手動テストでも確認できるが、何度も繰り返すため、 テストコードが一番効果的 と考えます
VS Codeは信頼している。デモのような 小さい範囲 はガンガンリファクタリング
ですが、テストコードがないとき、広い範囲に関わるならば私は見送ります
まずテストコード を用意しよう(武器『レガシーコード改善ガイド』)
📘『リファクタリング』にはまだまだテクニックが載っている
VS Codeがサポートしないテクニックは、テストコードを書いて、リファクタリング手順を練習して常中させていきましょう!
Martin Fowler著『リファクタリング』のテクニックをVS Codeの操作と結び付けて紹介
使い所(理論)とエディタの操作(身体)で覚えている 常中 状態の提案
変数名・関数名の変更➡️ F2 (Rename Symbol)
変数の抽出➡️ Extract variable
関数の抽出➡️ Extract method
特性の移動に関する数テクニック➡️ ⌥↑ ⌥↓ で始めよう
Enjoy development!
抽出の 逆操作 (リファクタリングは可逆な操作)
VS CodeやPython拡張ではサポートされないらしい(Marketplaceにあるかも)
VS Codeでできるリファクタリングには限界がある
もっと多くのリファクタリングについてサポートを受けて開発したい場合
👉IntelliJ IDEAやPyCharm
「常中」
リファクタリングテクニックは多数ある。まずは「ひとつのことを極め抜け」