Slide 1

Slide 1 text

初心者が リファクタリングで 目をつけるべき場所 【オンライン開催】フリーテーマLT【とらのあなLT】#13 水上皓登(きり丸)@nainaistar

Slide 2

Slide 2 text

リファクタリングとは ソフトウェアの外部の振る舞いを 保ったままで、内部の構造を改 善していく作業。

Slide 3

Slide 3 text

でも、何から手を付ければいい か分からない…

Slide 4

Slide 4 text

Code Smells に注目してみよう

Slide 5

Slide 5 text

話すこと / 話さないこと ● リファクタリングをする際に注目す るところ ● Code Smells ● リファクタリングの重要性 ● Design Pattern ○ 私が良く知らない ● やらないこと ○ ライブコーディング 話すこと 話さないこと

Slide 6

Slide 6 text

対象者 / 非対象者 ● リファクタリングをしたいけど、やり方 が分からない人 ● 新卒~3年目くらいのエンジニア ● 学生も含む ● リファクタリングに興味がない人 ● 新規機能の方が好きな人 対象者 非対象者

Slide 7

Slide 7 text

HN:きり丸(きりちゃん)   本名:水上 皓登 Twitter:nainaistar ブログ:きり丸の日記 7 サーバーサイドエンジニア

Slide 8

Slide 8 text

リファクタリングで 目指すのは、いいコード

Slide 9

Slide 9 text

どちらがいいコード? if (true) { } if (true) { } if (hoge == true){ } if (hoge != false){ } if (きのこの山 > たけのこの里){ } if (たけのこの里 > きのこの山){ }

Slide 10

Slide 10 text

いいコード  ≒  悪くないコード

Slide 11

Slide 11 text

リファクタリングで勉強する優先度 ● アンチパターン ○ 問題を発見する ● 見つける難易度は容易 ● 修正も簡単 ○ IDEで自動修正できる可能性が ある ● ★訓練がしやすい ● グッドパターン ○ 問題を解決する ● 解決できれば影響が大きい ● 難易度が高い ● 覚えると銀の弾丸のように思えてし まって、パターンに振り回されることも ある Code Smells Design Pattern

Slide 12

Slide 12 text

Code Smells の 一部抜粋 ★ Large Class ★ Long Method ★ Long Parameter ★ Duplicate Code ★ Magic Number ★ Comments ★ Arrow ★ Primitive Obsession ★ Feature Envy ★ Data Clumbs

Slide 13

Slide 13 text

Large Class 例なし ※わかりやすいけど、 ここから始めるのは地獄 巨大なクラス。 責務が多すぎる可能性がある ので、責務ごとの分割できる可 能性あり。 仕方ないことも往々にしてあ る。

Slide 14

Slide 14 text

Long Method 巨大なメソッド。 一つのメソッドで複数の処理を しようとしている可能性あり。 状況によっては仕方ない。 例なし ※LongMethodを 何とかするための記事は Appendix に 記載してます

Slide 15

Slide 15 text

Long Parameter public 学名 find学名( 界, 門, 亜門, 上綱, 綱 ) パラメータが3つ、4つ以上のメ ソッド。 Interfaceで必要なパラメータ のみを露出させることで、使用 するときはシンプルにできる。 public 学名 find学名( 界 ) { this.find学名( 界, null, null, null, null ); } ・・・

Slide 16

Slide 16 text

Long Parameter public 学名 find学名( 界, 門, 亜門, 上綱, 綱 ) または、共通項を見つけて、新 規のクラスにすることも有効。 ※主キー項目で一つのクラス にまとめるのはあり。 public 学名 find学名( 種別 ) public class 種別 { private 界 界; private 門 門; private 亜門 亜門; private 上綱 上綱; private 綱 綱; }

Slide 17

Slide 17 text

重複コード。 ただし、判断が難しい。 DRY(繰り返しを避ける)より、 SRP(単一責任の原則)を意識し たほうが良い。 Duplicate Code private static int userId = 0; private static int issueId = 0; public static int takeUserId() { return userId++; } public static int takeIssueId() { return issueId++; } private static int id = 0; public static int takeId() { return id++; } // あとから、userIdはUUIDで発行したくなっちゃった… // ※ UUID(Universally Unique Identifier) // 例 (550e8400-e29b-41d4-a716-446655440000) ?

Slide 18

Slide 18 text

Magic Number 固定値。 単純な数字ではなく、数字に意味 を持たせて表現する。 public void addPlayerPoint(){ switch (point) { case 0: this.point = 15; case 15: this.point = 30; case 30: this.point = 40; } } public void addPlayerPoint(){ switch (point) { case ZERO: this.point = ONE; case ONE: this.point = TWO; case THREE: this.point = FOUR; } }

Slide 19

Slide 19 text

Comments コメントが大量に 用いられている状態。 個人的にはJavaDocに書くのはOKだ が、JavaDoc嫌いな派閥もいる。 メソッドの責務が多すぎるときに 発生しがち。 例なし ※コメント書くなら意識したほ うがいい。 コードには How テストコードには What コミットログには Why コードコメントには Why not

Slide 20

Slide 20 text

Arrow if が大量に使用されている状態。 早期リターン や 別メソッドに切り出 して、脳みその一時領域を解放して あげるべき。 public void arrow(){ if (A != null){ if (B != null){ if (C != null){ if(D != null) {} } } } // ここで、AやBを使うかも… } public void arrow(){ if (A == null){ return; } if (B == null){ return; } ・・・ }

Slide 21

Slide 21 text

★ Primitive Obsession プログラムが用意した型しか使って いない状態。 プリミティブ型のint , long等 だけの話ではない。 自作型にすることで、fromXXToYY -> toYY だけで伝えられるようになる。 public String fromJaToEn(String ja){ return this.translate(ja); } public English toEn(Japanese ja){ return this.translate(ja); } public abstract class Language{ String 文字; } public class Japanese extends Language{} public class English extends Language{}

Slide 22

Slide 22 text

★ Primitive Obsession List や Mapも対象。 単純なListではない限り、 同じListでも違う挙動をする可能性 があるので、別クラスにした方が良 い。 通称:FCC (First Collection class) public class Duel{ List deck; // 山札 List trash; // 捨て札 List banish; // 除外 } public class Duel{ Deck deck; // 山札 Trash trash; // 捨て札 Banish banish; // 除外 } public class Deck{ List deck; } …

Slide 23

Slide 23 text

★ Feature Envy 別のクラスの値を使用して、処理し ている状態。 対象クラスの情報が流出してしまっ ている。 流出後の処理は追いづらく、リファ クタリングが困難になる。 public void Deck{ List deck; public Card searchMagicCard(){ for(Card card: deck){ String type = card.getType(); if (”magic”.equals(type)) return card; } } } public void Deck{ List deck; public Card searchMagicCard(){ for(Card card: deck){ if (card.isMagicCard()) return card; } } }

Slide 24

Slide 24 text

★ Data Clumbs 本来は一か所で管理されているべき、 データが散らばっている状態。 掲載開始、終了の掲載期間や X, Y, Zの座標等。 public class Notice{ String id; String description; LocalDateTime displayStart; LocalDateTime displayEnd; } public class Notice{ String id; String description; Term displayTerm; } public class Term { LocalDateTime start; LocalDateTime end; }

Slide 25

Slide 25 text

Code Smells の 一部抜粋 ★ Large Class ★ Long Method ★ Long Parameter ★ Duplicate Code ★ Magic Number ★ Comments ★ Arrow ★ Primitive Obsession ★ Feature Envy ★ Data Clumbs

Slide 26

Slide 26 text

Code Smells の 一部抜粋 ★ Large Class ★ Long Method ★ Long Parameter ★ Duplicate Code ★ Magic Number ★ Comments ★ Arrow ★ ドメイン知識不足 ○ Primitive Obsession ○ Feature Envy ○ Data Clumbs

Slide 27

Slide 27 text

おわりに リファクタリングは、行おうとする意思が無ければ、 問題を見つける力は身につきません。 既存の構造を崩さないまま、 新規の構造に変更していくリファクタリングは、 設計そのものとも言えます。 設計は高度な仕事です。 ぜひ、Code Smellsから設計力を磨いていってください。

Slide 28

Slide 28 text

Appendix

Slide 29

Slide 29 text

収まりきらなかった内容 ● SLAPを覚えてリファクタ リングをしよう https://nainaistar.hatenablog.com/entry/2020/06/22/SLAP%E3%82%92%E8%A6%9A%E3%81%88%E3 %81%A6%E3%83%AA%E3%83%95%E3%82%A1%E3%82%AF%E3%82%BF%E3%83%AA%E3%83 %B3%E3%82%B0%E3%82%92%E3%81%97%E3%82%88%E3%81%86/

Slide 30

Slide 30 text

参考資料 および テンプレート ● 使用テンプレート https://azusa3.sanographix.net/ ● Code Smells https://refactoring.guru/refactoring/smells ● 翻訳記事 http://qiita.com/taumax/items/f192b16676f78fa04849

Slide 31

Slide 31 text

参考資料 および テンプレート ● CSD研修 https://www.odd-e.jp/ja/service_csd/ ● CSD研修の講師のかたの直近の登壇 Scrum fest Osaka 2020 テスタビリティが低いシステムのためのテスティングテクニック -ライブコーディング https://confengine.com/scrum-fest-osaka-2020/proposal/14016/-