Rabbit Slide Show

リーダブルコード演習の概要

2022-11-02

Description

2022-08-04開催のリーダブルコード演習の概要と進め方の説明。

Text

Page: 1

リーダブルコードの意義
と、実践の方法
結城洋志
株式会社クリアコード
実践リーダブルコード
2022-11-02
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 2

全体の流れ
✓ リーダブルなコードの
意義と実践方法の説明
✓ 実装
✓ 実装を交換、続きを実装
✓ 全体で結果を共有
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 3

講師紹介
結城洋志(ゆうき ひろし)
aka Piro
✓ 株式会社クリアコード所属
✓ FirefoxやThunderbirdの
法人サポートに従事
✓ トラブルの原因や対策を探るため
ソースコードを調査することが多い
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 4

アジェンダ
✓ 講座の目的を確認
✓ リーダブルコードの
必要性を確認
✓ リーダブルコードの
実践方法を紹介
✓ 実践方法を練習
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 5

講座の目的
✓ リーダブルコードを
日常的に書く上での
基礎となる考え方
を実践し、持ち帰る
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 6

目的でないこと
✓ テクニックをたくさん覚える
✓ 難しいプログラムを実装する
✓ プログラムを速く実装する
✓ 高性能なプログラムを実装する
✓ 奇抜な方法で目立つ
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 7

ワークショップ後
✓ ぜひ実践を!
✓ 今日の資料はすべて再利用可能
✓ チーム内で同じ講座を再現できる
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 8


        

Page: 9

そもそもの話
✓ リーダブルコードはなぜ必要か
✓ 何の役に立つのか?
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 10

リーダブルコードが必要な理
由
✓ 既存のコードを読んで
素早く内容を把握したい
✓ 既存のコードに
素早く手を加えたい
✓ 開発速度を落としたくない
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 11

「速度」?
✓ 「読みやすさに気をつけたら
開発スピードが
落ちそう……」
✓ 「読みやすい書き方にしたら
実行スピードが
落ちそう……」
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 12

むしろ「読みにくいと開発が
遅くなる」
✓ 既存のコードを
理解しにくいと……
✓ 修正・機能追加に時間がかかる
(理解しないと変更できない)
✓ 後退バグが発生しやすい
(理解しないまま変更すると問題発生)
→コストがかかる
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 13

時間が経つほど影響大
開発
速度
リーダブルな場合
開発速度が落ちにくい
リーダブルじゃない場合
開発速度が落ちやすい
時間
(注意:グラフではなく概念図です)
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 14

つまり
✓ 現実的なコストの範囲で
✓ 既存のコードを継続的に、
無理なく改良・修正したい
→なので、リーダブルコード
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 15

既存のコードに手を加える場
面
✓ 新機能を追加するとき
✓ 不具合を修正するとき
業務での開発は、全く0からの新規開発でない限り既存のコード
に手を加えることの方が多い
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 16

手を加えられないコードは業
務上のリスク
✓ 分かる人が1人しかいない→危険
✓ 実装者が抜けたら詰む
✓ 変更できてもものすごくコストがかかる
↓
チームで開発し、
チームの誰でも作業を引き継げる
状態にしておきたい
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 17


        

Page: 18

リーダブルコードの実践
どうすれば無理なく実践できる?
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 19

リーダブルコードの実践
コードを読む
習慣を作る
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 20

読む?書くじゃないの?
✓ リーダブルコードを書くには
コードを読むことが欠かせない
✓ なぜ?
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 21

コードを読むのが大事な理由
✓ 何が「読みやすい」か
読む側でないと
分からないから
✓ 書いている最中は
読みやすさ・読みにくさ
を実感しにくいから
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 22

何が「読みやすい」かは受け
手の状況次第
✓ しょっぱいのが好きな人と
甘いのが好きな人で
「おいしい」の基準は違う
✓ 自分はどんな味が好みか?
✓ 日常の運転とレースでは
「乗りやすい」の基準は違う
✓ 自分はどんな乗り方をするのか?
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 23

リーダブルコードも同じ
✓ チームの状況によって
「リーダブル」の基準が違う
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 24

リーダブルコード
「読む人」が
読みやすいなら
リーダブル
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 25

チーム内で「リーダブル」の
基準を共有しよう
✓ どんなコードをどんな理由で
「リーダブル」と感じたのか
自己分析してみる
✓ 本で紹介されている書き方が
本当に自分達にとっても
「リーダブル」なのか確かめる
(実践パートでやってみよう)
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 26

何が「読みやすい」か分かっ
ていても…
✓ コードを書いている最中は
読みやすさ・読みにくさを
実感しにくい
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 27

実際のコードで考えてみる
✓ Excelワークシートの生成で
見出しセルを結合する関数
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 28

やりたいことを言語化してみ
る
関数 項目の見出し列(B~C)のセルを結合する(行番号, 項目):
項目の選択肢の数が1以下だったら:
何もせず終了
そうでないなら(選択肢が2つ以上あるなら)、
「見出し列の定義の配列」の全要素について、 要素の番号 を使って:
シートの範囲を結合(
開始行 → 行番号,
開始列 → 要素の番号,
終了行 → 行番号 + 選択肢の数 - 1,
終了列 → 要素の番号)
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 29

項目の見出し列の……
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 30

セルを結合する
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 31

見出し列の定義の配列
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 32

シートの範囲を指定して結合
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 33

実際のコード
def m(s, n, i):
if len(i['o']) <= 1:
return
s2 = s.s
for i2, c in enumerate(hcol):
s2.merge_range(n, i2,
n + len(i['o']) - 1, i2,
'')
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 34

書いた本人の視界
関数 項目の見出し列(B~C)のセルを結合する(行番号, 項目):
項目の選択肢の数が1以下だったら:
何もせず終了
そうでないなら(選択肢が2つ以上あるなら)、
「見出し列の定義の配列」の全要素について、
要素の番号 を使って:
シートの範囲を結合(開始行番号, 開始列番号,
開始行番号 + 選択肢の数 - 1, 終了列番号)
----------------------------------------------------------
def m(s, n, i):
if len(i['o']) <= 1:
return
s2 = s.s
for i2, c in enumerate(hcol):
s2.merge_range(n, i2,
n + len(i['o']) - 1, i2,
'')
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 35

第三者の視界
def m(s, n, i):
if len(i['o']) <= 1:
return
s2 = s.s
for i2, c in enumerate(hcol):
s2.merge_range(n, i2,
n + len(i['o']) - 1, i2, '')
------------------------------------------------
関数 何か(何か, 何か, 何か):
何かの数が1以下だったら:
何もせず終了
そうでないなら、
何か = 何かが保持している何か
何かについて、 何か を使って:
何かの範囲を結合(何か, 何か,
何か + 何か - 1, 何か)
前情報無しだと、意味ある情報を読み取るのは困難……
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 36

リーダブルなコードの場合
def try_merge_item_heading(self, row, item):
if len(item['options']) <= 1:
return
sheet = self.sheet
for index, _column in enumerate(HEADING_COLUMNS):
sheet.merge_range(row, index,
row + len(item['options']) - 1, index,
'')
-----------------------------------------------------------
関数 項目の見出しセルを結合してみる(自分, 行, 項目):
項目の選択肢の数が1以下だったら:
何もせず終了
そうでないなら、
シートは自分が保持している
見出しの列 の全項目について、 番号 を使って:
シートの、範囲を結合( 行, 番号,
行 + 項目の選択肢の数 - 1, 番号,
'')
先の例よりは意味のある情報を読み取れるはず
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 37

よく聞く話
✓ 手紙を書いたら一晩寝かせろ!
✓ 試験の回答文は、最後に
もう一回読み返せ!
前提を知らない読み手
の気持ちになろう
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 38


        

Page: 39

実際のコードを読んでみよう
Excelのワークシートを
自動生成するPythonスクリプト
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 40

ビジネス上の要件
✓ Firefoxを法人運用向けに
設定したい
✓ 設定を一覧で管理したい
✓ 「自動更新:有効/無効」など
✓ 顧客ごとに設定内容を変えたい
✓ バージョンごとの変化を見たい
✓ Firefox 78からFirefox 91の間で
追加された設定、廃止された設定
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 41

元々はExcelワークシートを
手作りしていた
✓ Gitでバージョン管理しにくい
✓ 同じ変更内容を複数顧客の
ワークシートに反映するのに
手間がかかる
どうにかしたかった
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 42

自動化を図った
✓ 資料自体を
バージョン管理しやすく
✓ プレーンテキスト形式のソースから
Excelワークシートを自動生成
✓ 1. 設定項目の定義
✓ 2. 前バージョンのFirefox用の設定情報
✓ 3. 今バージョンのFirefox用の設定情報
✓ 初版はPythonに慣れた人が実装
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 43

読んでみよう1
build-xlsx-1.py
ざっと見て概要を掴んでみよう
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 44

ポイント
✓ 少数の短い関数
✓ 分かりやすい名前付け
✓ 列番号はべた書き
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 45

試しに探してみよう1
✓ 「...→...での変更」の列に
「新規」と出力する条件は
どこで判定している?
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 46

試しに読んでみよう2
build-xlsx-2.py
第三者が手を加えた物
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 47

改修の経緯
✓ 要件が増えた
✓ 比較対象の数が可変になった
✓ 改修前:「Firefox 78」と
「Firefox 91」
✓ 改修後:「Firefox 78」と
「Firefox 91(デスクトップPC)」
「Firefox 91(ノートPC)」...
✓ 行数は約1.2倍に増加
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 48

試しに探してみよう2
✓ 「検証手順書対応番号」
の列に出力する内容は
どこで決まっている?
さっきより大変なはず
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 49

リーダブルだった書き方がア
ンリーダブルに……
✓ 関数の数が少ない
✓ 個々の関数が肥大化し、
全体像の把握が困難に
✓ if-elif/elseでの条件分岐
✓ 階層が複雑化して
処理の実行条件を追いにくい
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 50

試しに読んでみよう3
build-xlsx-3.py
大幅に改修した物
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 51

改修の要旨
✓ 複雑化した問題に合わせて
「リーダブル」の基準を変えた
何がリーダブルかは状況に依存する
✓ 定数を使う部分を増やした
✓ メソッド・変数のスコープを小さく
✓ コードの行数は約1.5倍に増加
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 52

試しに探してみよう3
✓ 「検証済み」という列を
「検証手順書対応番号」
の列の右隣に追加したい
(セルの内容は空でよい)が、
どこに手を入れればいい?
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 53

試しに探してみよう3
✓ 「検証済み」という列を
「検証手順書対応番号」
の列の右隣に追加したい
(セルの内容は空でよい)が、
どこに手を入れればいい?
✓ →探し方のコツがある
✓ 改修前:全体を読んで覚えて探す
✓ 改修後:必要な部分だけ読んで探す
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 54

つまり、ここでの「リーダブ
ル」とは
✓ 全体を一望するのが難しい
複雑なコードについて
✓ 一度に読むことは諦めて
✓ 必要な部分だけ読む
という前提での「読みやすい」
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 55

ふつうのOSS開発者の日常
✓ × イメージ
✓ コード全体を詳細・完璧に把握
✓ ノールックで修正
✓ ◯ 実態
✓ 全体像はボンヤリ把握
✓ 都度必要な部分を読み直して
調べ直しながら修正
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 56

自分で書いたコードでも、覚
えてないのが当たり前!
✓ 覚えておかなくていいように
するのがリーダブルコード
✓ 書籍「リーダブルコード」
巻末の「解説」も読んでみて!
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 57


        

Page: 58

リーダブルコードの実践
✓ 別の切り口でも考えてみよう
✓ なぜアンリーダブル化する
のか?
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 59

アンリーダブル化する原因
考えてみよう
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 60

アンリーダブル化する原因
(例)
✓ コードを書き換えないから
アンリーダブル化する
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 61

理想的な変更の流れ
1. 要件に従って設計する
2. 設計通り実装する
3. 要件に従って設計する
4. 設計通り実装する
5. ...
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 62

悪くない変更の流れ
1. とりあえず動くようにする
2. 設計を見直して整理する
3. とりあえず動くようにする
4. 設計を見直して整理する
5. ...
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 63

アンリーダブル化しやすい流
れ
1. とりあえず動くようにする
2. とりあえず動くようにする
3. とりあえず動くようにする
4. ...
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 64

設計は随時見直さないといけ
ない
✓ 設計が状況の変化に
追従できていない
✓ コードの規模や前提は
徐々に変化する
✓ 気付かないうちに進行する!
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 65

状況の変化に気付けても、追
従できない……
✓ 既存のコードを書き直せない
✓ 書き直して動かなくなるのが怖い
✓ 「とりあえず動くように」で焦って
「書き足す」一辺倒になる
✓ 冷静に見直す余裕がない
→良くない兆候を見て見ぬフリ
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 66

ベテランはどうする?
✓ 悪い兆候を見逃さない
✓ 既存のコードを
書き直すのをためらわない
✓ 書き直さない方が、
後で痛い目を見ると知っている
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 67

悪い兆候に敏感になろう
✓ マメに読み返していると、
アンリーダブルのなり始めに
すぐ気付ける
✓ 「アンリーダブルに
なり始めてる……?」
→書き直しを考えるタイミング
後回しにしない!
(すぐやらないなら、せめてコメントを残す)
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 68

ためらわずに書き直せるよう
にするために(1)
✓ わけが分からないままにしない
✓ 自分が今何をしているかを
正しく理解するよう努めてる
✓ 不安が少しでも生じたら
立ち止まって考える
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 69

ためらわずに書き直せるよう
にするために(2)
✓ 便利な道具で補う
✓ 自動テストで結果の同値性を保証
自動テストは大事!
✓ Gitでいつでも巻き戻せる安心感
バージョン管理システムは大事!
✓ コードフォーマッターで
安全にコードを整形
「リーダブルにする」はある程度自動化できる
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 70

早め早めのリカバリー
✓ なるべく早くリーダブルに直す
✓ 書く→直す のサイクルを回す
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 71

参考:良い分割の仕方(1/2)
✓ "良いコードとは何か - エンジ
ニア新卒研修 スライド公開"
✓ https://note.com/cyberz_cto/n/
n26f535d6c575#E0aBe
✓ サイバーエージェント社の新卒研修の資料
✓ 「凝集度と結合度」が参考になる
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 72

参考:良い分割の仕方(2/2)
✓ 良いコード/悪いコードで学ぶ
設計入門
―保守しやすい 成長し続ける
コードの書き方
✓ 著:仙塲 大也
✓ 刊:技術評論社
✓ 通称「ミノ駆動本」
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 73


        

Page: 74

リーダブルコードの練習
✓ 読まれる前提で
コードを書いてみよう
✓ コードを書く→読む→直す
のサイクルを体験しよう
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 75

体験学習
✓ 11:55-14:15 課題を実装
✓ リーダブルコードを書く
✓ 14:30-15:45 実装チェンジ
→開発継続
✓ 「まず自分が読み始める」
✓ 「リーダブルコードを探す」
✓ 16:00- グループふりかえり
✓ 「他のメンバーと共有」
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 76

おさらい
✓ 講座の目的?
✓ リーダブルコードの必要性?
✓ 講座でやること?
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 77

講座の目的
✓ リーダブルコードを
日常的に書く上での
基礎となる考え方
を実践し、持ち帰る
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 78

リーダブルコードが必要な理
由
✓ 既存のコードを読んで
素早く内容を把握したい
✓ 既存のコードに
素早く手を加えたい
✓ 開発速度を落としたくない
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 79

変更コストと開発速度
開発
速度
リーダブルな場合
開発速度が落ちにくい
リーダブルじゃない場合
開発速度が落ちやすい
時間
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 80

講座でやること
✓ コードを読む文化作りの体験
✓ 自分がコードを読んでみる
✓ 読まれる前提でコードを書いてみる
✓ 他の人とリーダブルコードの
基準を共有する
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Page: 81

ここまでの説明
腑に落ちました
か?
リーダブルコードの意義と、実践の方法
Powered by Rabbit 2.2.1

Other slides