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
ソースコードを美しくたもつために ~コードレビューの認知限界を突破し、年間400リリースを達成する~
Search
kotauchisunsun
May 11, 2024
Programming
1
12k
ソースコードを美しくたもつために ~コードレビューの認知限界を突破し、年間400リリースを達成する~
2024/05/11に開催されたPHPカンファレンス香川にて発表
https://phpcon.kagawa.jp/2024/
kotauchisunsun
May 11, 2024
Tweet
Share
More Decks by kotauchisunsun
See All by kotauchisunsun
スマートグラスの重量と価格に関する課題の整理とアプローチについて
kotauchisunsun
0
19
スマートグラスのトリレンマ
kotauchisunsun
0
38
2025年上半期のスマートグラスの概況
kotauchisunsun
0
97
どのAI Coding Agentが一番使われてる? ~ ai-coding.info にみるGithubリポジトリのAI Coding Agent利用状況 ~
kotauchisunsun
0
740
OpenHands🤲にContributeしてみた
kotauchisunsun
1
810
A-Scouterの紹介 ~AtomS3/S3Rのスカウター化キット~
kotauchisunsun
0
95
今、スマートグラスが熱い。
kotauchisunsun
0
220
RooCodeによる開発の夢と実践の現実
kotauchisunsun
0
850
書籍「テスト駆動」が 教えてくれること 教えてくれないこと 知っておくべきこと
kotauchisunsun
0
150
Other Decks in Programming
See All in Programming
Improving my own Ruby thereafter
sisshiki1969
1
160
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
0
390
サーバーサイドのビルド時間87倍高速化
plaidtech
PRO
0
720
請來的 AI Agent 同事們在寫程式時,怎麼用 pytest 去除各種幻想與盲點
keitheis
0
100
Amazon RDS 向けに提供されている MCP Server と仕組みを調べてみた/jawsug-okayama-2025-aurora-mcp
takahashiikki
1
110
「手軽で便利」に潜む罠。 Popover API を WCAG 2.2の視点で安全に使うには
taitotnk
0
830
Flutter with Dart MCP: All You Need - 박제창 2025 I/O Extended Busan
itsmedreamwalker
0
150
旅行プランAIエージェント開発の裏側
ippo012
2
890
テストコードはもう書かない:JetBrains AI Assistantに委ねる非同期処理のテスト自動設計・生成
makun
0
240
AI時代のUIはどこへ行く?
yusukebe
16
8.7k
Navigation 2 を 3 に移行する(予定)ためにやったこと
yokomii
0
120
複雑なドメインに挑む.pdf
yukisakai1225
5
1.1k
Featured
See All Featured
The Pragmatic Product Professional
lauravandoore
36
6.9k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Done Done
chrislema
185
16k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
Making Projects Easy
brettharned
117
6.4k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.9k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
111
20k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3k
Bash Introduction
62gerente
615
210k
Being A Developer After 40
akosma
90
590k
Transcript
ソースコードを美しくたもつために ~コードレビューの認知限界を突破し、年間400リリースを達成する~ @kotauchisunsun
自己紹介 ~仕事編~ • @kotauchisunsun • 株式会社STYLY 2019年入社 • サーバーサイド責任者 • プラットフォーム部
EM
自己紹介 ~個人編~
今日お話しする話の元ネタ
サーバーサイドのリリース回数が年間418回を達成 最大は1か月80回!!
サーバーサイドのソースコードの自動テストのカバレッジ (Googleの平均テストカバレッジは79%らしい・・・・)
当時の開発体制 委託 委託 企画・設計 開発 レビュー
当時の開発体制 委託 委託 企画・設計 開発 レビュー PRレビューが全部私に来る
年間400件超のコードレビューを頑張った話
コードレビューの効率をあげたい
コードの見る行数を減らそう
コードレビューの着眼点 仕様とプログラムが 合致しているか それ以外 • それ以外 ◦ タイポしている ◦ 1行が長すぎる
◦ 1クラスが大きすぎる ◦ 関数の引数が多すぎる ◦ 非推奨の関数を使っている ◦ コードのにおい ◦ バッドプラクティス 「それ以外」を見る工数を限りなく削減しよう
Linter/静的解析の導入 PHP-CS-Fixer PSR-2(コード規約チェック) PHPMetrics LCOM・循環複雑度 SonarQube コードのにおいの検出 複数の視点からコードレビューの自動化を行った
コードレビューの効率はあがった
なぜか?
コードレビューは難しい
コード 原則1 原則2 原則3 ・・・ 原則N ②自分の脳内の原理原則一覧を列挙し、 ③該当する原則を思い出し、 ④その原則の妥当性を示し、 ①原則に違反してそうな部分を見つけ、
⑥修正方針を示す “仕様と実装の一致以外”ー≒”コードの良さ”のコードレビュー 結構大変。 レビュー ⑤コードが原則に違反している こ とを示し、 例:動詞から始まらない関数の命名
SonarQube(SonarCloud)の場合 ①どのようなコードのにおいか? ②ソースのどの箇所で発生してるか? ③どのように修正すべきか? SonarQubeがレビューのフローを ほぼ自動でやってくれる
コードレビューで考えることが少なくなった
コードレビューの効率はあがった
それでもうまくいかない部分があった
WebApiInterface コードの一貫性の破れ UserController PostController FavoriteHandler MessageController ほかのクラス群はControllerで統一されて いるのにクラスの命名がHandlerとして実 装してしまう。 既存のツールでは対応できない。
PHPのリフレクション機能 プログラム内で定義されたクラスの名前が全て 取得できる関数 各クラスの定義情報が取得できるクラス
ReflectionClass /* プロパティ */ public string $name; //クラス名 /* メソッド
*/ public getAttributes(?string $name = null, int $flags = 0): array public getConstants(?int $filter = null): array public getDocComment(): string|false public getExtensionName (): string|false public getFileName(): string|false //ファイル名 public getInterfaceNames (): array //インターフェース一覧 public getMethods(?int $filter = null): array //メソッド一覧 定義済みのクラスの情報がほぼ全て取れる。 get_declared_classes+ReflectionClassで社内事情にあった簡易Linterの作成。 簡易LinterによるチェックはPHPUnitのテストケースとして相乗り。
ルールの一例 • Controllerパッケージのクラス名はControllerをsuffixとする • Applicationパッケージのクラス名はApplicationをsuffixとする • コンストラクタの引数には型必須 • 関数の引数には型必須 •
関数の返り値には型必須 • ファイルの行数は1,000行以下 • 作成日時(created_at)など日時をあらわす引数は日時型(Carbon)とする PHP-CS-Fixerで実現できない細かいルールも追加 社内独自の一貫性も確保できるようになった
別に意外な副産物があった
今までのコードレビュー 既存コード 委託 追加コード このコードは既存コードのルー ルと逸脱しており、 社内では〇〇という ルールで実装しています。 修正お願いします。
Linterを作成しての気づき 委託 既存コード 追加コード ルール1 Linter1 自分では曖昧性のないルールで運用しているつもりだが、 Linterのルール として実装できない矛盾を含んだルールだった。 ルール2
Linter2 Linterとして実装できて、自分としては守っているつもりのルール が、既存コードが守られていなかった。 • いかに自分のコード (一貫性)に関する認識が甘かったかを痛感。 • 論理矛盾のないルールは検証なしで設計できない。 • 厳格で精緻な運用ができるしすべきと思うならプログラムに実装できるはずで、 それなら自分で実装して運用すべき。
もう1つの効果
当初のリリースサイクル 委託 開発 レビュー 開発 レビュー リリース コードの品質を上げる方法が コードレビューしかない。 人力コードレビューがボトルネック
改善後のリリースサイクル 委託 開発 開発 レビュー リリース 既存ツール 自作Linter チェック コードの品質が上がるので
・レビュー時間が短縮 ・差し戻し回数が削減 開発からリリースまでの時間が短縮 →年間400超リリース出来た コードの品質向上が開発者で完結 レビュー待ち時間の削減 開発時間の増加
コードレビューの観点の再分解と効率化 仕様とプログラムが 合致しているか それ以外 既存ツールで対処 自作Linterで対処 一般的なプラクティス 社内固有プラクティス 仕様とプログラムが 合致しているか
ツールにより見るべきソースコードが削減できた。 →大量のレビューができるようになった。
直感的には正しそう。
本当?
別視点から整理してみたい
18章 近年のコードレビュー ジェイソン・コーエン(Jason Cohen)
コードレビュー時間と欠陥の発見数の関係 (引用) ところが60分後あたりで、 突然の落ち込みがあります。(中略) 欠陥発見の効率は急激に落ち込みます。 長時間のコードレビュー疲労してバグを見逃すので、 1回のコードレビューは 1時間まで Dunsmore, A.,
M.Roper, and M. Wood. 2000. Object-Oriented Inspection in the Face of Delocalisation. Proceedings of the 22nd International Conference on Software Engineering 2000: 467-476. 横軸:レビュー時間 縦軸:欠陥数
レビュー速度と欠陥密度の関係 (引用) 問題は、400~500LOC/時を超える 早いレビューにあります。 突然、欠陥密度の高いレビューは 稀になります。(中略) レビュー担当者が速く進めすぎて 欠陥を見つけ損なっているからです。 速すぎるコードレビューはバグを見逃すので、 レビュー速度は400行/時未満にすべき
Cohen, Jason. 2006. Best Kept Secrets of Peer Code Review. Baberly, MA: SmartBear Software 横軸:レビュー速度(LOC/時) 縦軸:欠陥密度(欠陥数/kLOC)
コードレビューの限界 (引用) レビューは最大で1時間にすべきであり、(中略) 1回 のレビュー対象は400行を超えてはいけないという結 論になります。 • 1回のコードレビューは1時間まで • 1回のコードレビューは400行まで
人間のコードレビューの量に限界がある。 横軸:レビュー対象の行数(LOC) 縦軸:欠陥密度(欠陥数/レビュー時間)
既存ツールの導入や 自作ツールの開発により コードレビュー量は増やせる。 人間のコードレビューには 限界がある。 1回1時間、400行までしか コードレビューができない。 矛盾?
ちょっと別の話
認知負荷理論 参考:https://atlassian-teambook.jp/_ct/17574839 オーストラリアの教育心理学者、ジョン・スウェラー(John Sweller)氏によって1980年代に開発・確立された理論 脳のワーキングメモリが常に処理している「情報量」を指 し、脳への情報のインプットが私たちの認知能力にどのよう な負担をかけるかを表している。
認知負荷の3つのタイプ • 課題内在性負荷(Intrinsic Cognitive Load) ◦ 情報の内容を理解するのが困難な度合い • 課題外在性負荷(Extraneous Cognitive
Load) ◦ 気を散らせる情報や事象といった外的要因によって引き起こされる認知の 負荷 • 学習関連負荷(Germane Cognitive Load) ◦ 脳がスキーム(世界を理解するための枠組み)を構築しているときに発生す る。スキームの構築・蓄積により、同様な状況で適切な判断ができるように なる。 参考:https://atlassian-teambook.jp/_ct/17574839
ダンスを学ぶ時の認知負荷の解釈 音楽に合わせて、腕を振 り上げて・・・・ 右足をあげて、右手をに ぎって、上体を反らして ・・・ ダンスを学ぶために スマホで検索して・・・ 課題内在性負荷 学習関連負荷
課題外在性負荷 ※発表者は専門家ではありません
コードレビューの認知資源の内訳 課題 内在性 負荷 課題 外在性 負荷 人間の耐えられる認知負荷の限界 課題 外在性
負荷 課題 内在性 負荷 余力 課題外在性負荷を 減らすことができれば、レ ビュー量が増やせる?
コードレビュー効率化の実践と認知負荷理論の接合 仕様とプログラムが 合致しているか (課題内在性負荷) それ以外 (課題外在性負荷) 一般的なプラクティス 社内固有プラクティス 仕様とプログラムが 合致しているか
(課題内在性負荷) 人間の耐えられる認知負荷の限界 = 人間のコードレビューできる限界 コードレビューできる規模が増えた 自作・既存ツールで 節約した情報量 MakingSoftwareの結論と認知負荷理論に矛盾することなく今回の手法と成果を整理できた。 →今回のレビュー効率化の手法はおそらく有効そう?
まとめ • 2022年にコードレビューが急増した • コードレビューの効率化を行った ◦ 既存ツールの導入・自作Linterの開発 • 自作Linterの開発で自分のコードに関する認識を改めた ◦
自分のコード規約の矛盾の認知・一貫性の欠如 • コードレビューの改善によりリリースサイクルが短縮化された • コードレビューは1時間の間に、1回400行未満にしないとバグを見逃す危険性が高まる。 • 認知負荷には3種類ある ◦ 課題内在性負荷・課題外在性負荷・学習関連負荷 • 大量のコードレビューが可能になった理由は、既存ツール・自作 Linterの開発により課題外 在性負荷を軽減することで、仕様と実装の不一致の確認に認知資源を注力できたことによ るものだと整理できた • 課題外在性負荷の軽減により年間400超のリリースが実現できた
というわけで
みなさんCI/CDやってますか?
静的解析・Linter動かしてますか?
自動テスト書いてますか?
千里の道も一歩から
がんばっていきましょう。