Slide 1

Slide 1 text

名は体を表していますか ~名前から見るコード~

Slide 2

Slide 2 text

自己紹介 ● 名前: ナカノ アキラ ● 年齢: 33歳 ● 結婚してます。つい先日10周年でした。 ● 趣味: お菓子(おやつ)作り

Slide 3

Slide 3 text

お察し力

Slide 4

Slide 4 text

お察し力 あなたの近くに優秀なプログラマはいますか?

Slide 5

Slide 5 text

お察し力 何をもって優秀か ● データベースに精通している ● 設計に関する知識が高い ● オールマイティに全範囲こなせる ● ...etc

Slide 6

Slide 6 text

お察し力 仕様把握や、状況理解の早い人 = 「お察し力」が高い人 というのもあると思います

Slide 7

Slide 7 text

お察し力 「お察し力」が高い人 チーム内に何人いますか?

Slide 8

Slide 8 text

お察し力 「お察し力」が高い人に頼る場面 ● 既存コードからの仕様把握 ● 不可解なバグの解析 ● コードレビュー ● ...etc

Slide 9

Slide 9 text

お察し力 「お察し力」が高い人に頼る場面 ● 既存コードからの仕様把握 ● 不可解なバグの解析 ● コードレビュー ● ...etc ある種の属人化!!

Slide 10

Slide 10 text

お察し力 「お察し力」が求められないコード ● 保守性が高い ● 属人化の進行が遅い ● 引き継ぎコストが安い

Slide 11

Slide 11 text

お察し力 「お察し力」が求められないコード ● 保守性が高い ● 属人化の進行が遅い ● 引き継ぎコストが安い ○ プロジェクト価値が高い ○ 会社に対して明確なメリット

Slide 12

Slide 12 text

お察し力 どうすればよいか? 簡単なところから始める 「名前の力」 を借りてみるというのはどうか

Slide 13

Slide 13 text

変数

Slide 14

Slide 14 text

変数 ● 一般に省略は悪とされる ○ 意味がなくなる ○ 読み手の負担が増える ○ 違和感が隠れる

Slide 15

Slide 15 text

変数 第一にぱっと見わからない ● $sd; //skill_damage ● $sp; //skill_point ● $spd; //speed 読み手がデコードしなければならない

Slide 16

Slide 16 text

変数 第一にぱっと見わからない ● $sd; //skill_damage ● $sp; //skill_point ● $spd; //speed 読み手が記憶しておかなければならない

Slide 17

Slide 17 text

変数 第一にぱっと見わからない ● $sd; //skill_damage ● $sp; //skill_point ● $spd; //speed 他の場所ではspがspeedの省略だったりする

Slide 18

Slide 18 text

変数 違和感に蓋をしない ● $w->getName(); ● $wood->getName(); 後者は少し気になるコード、木材に名前がある

Slide 19

Slide 19 text

変数 違和感に蓋をしない ● $w->getName(); ● $wood->getName(); wでは名前として認識できず意識が向かない

Slide 20

Slide 20 text

変数 状態をかき混ぜない $not_disable_exclude_filter = false; 読み手どころか、書いた本人もわからないのでは・・・

Slide 21

Slide 21 text

変数 状態をかき混ぜない $not_disable_exclude_filter = false; ここまでひどいのは、あまりないですが not_disable_hogeぐらいは割と見ます。

Slide 22

Slide 22 text

変数 ● 読み手の負担を考える ● 単語の省略はしない ● 読み手が欲しい情報を提供する

Slide 23

Slide 23 text

関数名

Slide 24

Slide 24 text

関数名 ● 一般的に動詞が良いとされる ● 名前以上のことをしない ● 名前を綺麗につけようとしない ● 内部の処理を抽象化して表す

Slide 25

Slide 25 text

関数名 function giveReward($id){ $reward = fetchRewardMaster($id); storeReward($reward); sendNotification(‘%sを受け取った’, $reward->name()); // 通知 }

Slide 26

Slide 26 text

関数名 function giveReward($id){ $reward = fetchRewardMaster($id); storeReward($reward); sendNotification(‘%sを受け取った’, $reward->name()); // 通知 } giveRewardは fetchRewardMaster と storeReward を抽象化した名前 sendNotificationが含まれている名前には見えない

Slide 27

Slide 27 text

関数名 function giveReward($id){ $reward = fetchRewardMaster($id); storeReward($reward); sendNotification(‘%sを受け取った’, $reward->name()); // 通知 } もっと愚直に名前を付けてみよう

Slide 28

Slide 28 text

関数名 function giveRewardAndNotice($id){ $reward = fetchRewardMaster($id); storeReward($reward); sendNotification(‘%sを受け取った’, $reward->name()); // 通知 } わかりやすい名前をつけるということは、見た目を取り繕うことじゃない やっていること(大事なこと)を書いて読み手に伝えるのは大切だと思う

Slide 29

Slide 29 text

関数名 function giveRewardAndNotice($id){ $reward = fetchRewardMaster($id); storeReward($reward); sendNotification(‘%sを受け取った’, $reward->name()); // 通知 } さらに、この関数を一言で表す(より抽象化された)名前は無いだろうか? 名前(境界)が存在しないなら、処理の境界も存在しないかもしれない

Slide 30

Slide 30 text

関数名 これはハンバーガーですね。

Slide 31

Slide 31 text

関数名 これはなんでしょう

Slide 32

Slide 32 text

関数名 function giveRewardAndNotice($id, $send_notice){ $reward = fetchMasterReward($id); storeReward($reward); if ($send_notice) sendNotification(‘%sを受け取った’, $reward->name()); } 処理境界を間違えていると、そのうちこんなコードになる

Slide 33

Slide 33 text

関数名 ● やっていることを書こう ● 処理を抽象的に表す名前(境界)を探そう ● 名前が無い時は正しいか考えよう ○ もちろん合っている時もある ● 境界は作るものによって変わる ○ 絶対は存在しない ○ 途中で変わることもある

Slide 34

Slide 34 text

関数名 Andが悪いという話じゃないよ ● FWやユーティリティなど ○ それより上の概念が存在しない ● 単純に処理を繋げてコード記述量を減らしたい ○ 複数の処理を一度に呼び出すことが多い ○ 独立した処理も別にあると良いと思う

Slide 35

Slide 35 text

クラス名

Slide 36

Slide 36 text

クラス名 ● 一般的に名詞が良いとされる ● 可能な限りそれを表す名詞を探す ● 曖昧な名前、包括的な名前を使わない ○ 無意味なManager, Serviceなど ○ 境界線が曖昧になる ○ 名前の力が薄れる

Slide 37

Slide 37 text

クラス名 class NotificationService{ function sendNotification(); } A「メッセージ送信クラスを作ったぞ」 A「送信機能しか持たせていないシンプル イズ ベスト」 A「名前はなんか思いつかなかったしサービスでいいや」

Slide 38

Slide 38 text

クラス名 class NotificationService{ function sendNotification(); } B「通知サービスクラスか」 < この時点で認識が違う B「通知テキストの管理もここでいいかな」

Slide 39

Slide 39 text

クラス名 class NotificationService{ function sendNotification(); function addNotificationText(); function removeNotificationText(); } C「サービス!なんでもできる。いわゆるゴッド!!」 C「受け取り処理もここでいいっしょ」

Slide 40

Slide 40 text

クラス名 class NotificationService{ function sendNotification(); function addNotificationText(); function removeNotificationText(); function recieveNotification(); } A「送信クラスだったのに・・・なんでメッセージ管理とか受信処理まで」

Slide 41

Slide 41 text

広く受ける名前 クラス名 受信機能 送信機能 テキスト コンテナ

Slide 42

Slide 42 text

広く受ける名前 クラス名 受信機能 送信機能 テキスト コンテナ 大は小を兼ねない

Slide 43

Slide 43 text

程よい名前 クラス名 受信機能 送信機能 テキスト コンテナ 程よい名前に いい感じの名前

Slide 44

Slide 44 text

クラス名 class NotificationSender{ function sendNotification(); } A「メッセージ送信クラスはを作ったぞ」 A「送信機能しか持たせていないシンプル イズ ベスト」 A「今度は名前も明示的かつ限定的」

Slide 45

Slide 45 text

クラス名 class NotificationSender{ function sendNotification(); } B「通知送信クラスか」 B「通知テキストをどこかにまとめたいんだけど、送信者はちょっとなー」 B「NotificationTextContainerとかつくるかー」

Slide 46

Slide 46 text

クラス名 class NotificationSender{ function sendNotification(); } C「通知の受信処理つくろ!」 C「Senderにrecieve()とか、さすがに違うか」 C「素直にNotificationReceiverつくるか」

Slide 47

Slide 47 text

クラス名 ● 必要以上の意味を持つ名前を付けない ○ 境界が曖昧になる ○ 名前の力が薄まる ● 適切な境界を持つ名前なら構造を守れる ○ 相手に求めず自己防衛力のある名前を

Slide 48

Slide 48 text

クラス名 ServiceやManager等は使っちゃダメなのか?

Slide 49

Slide 49 text

クラス名 ServiceやManager等は使っちゃダメなのか? ● 明確な意味を持たない用語 ● 自分たちで意味を持たせることができる ● ルールを作って使うのはどうか ● 例えばファサードをServiceと呼ぶなど ● アーキテクチャによっては役割が決まっている ● やりすぎると負担になるので注意

Slide 50

Slide 50 text

まとめ

Slide 51

Slide 51 text

まとめ ● 名前は体を表さなければならない ● 名前は処理境界を作る(そして守る) ● 名前は設計の問題をあぶり出す ● 名前は違和感を際立たせる ● 名前は読み手の負担を減らす

Slide 52

Slide 52 text

まとめ 自分の「お察し力」は頑張って磨こう 相手に「お察し力」を求めるのはやめよう 名前を考えるだけでだいぶ負担は減る(と思う)

Slide 53

Slide 53 text

以上、ありがとうございました。