Upgrade to Pro — share decks privately, control downloads, hide ads and more …

初心者がリファクタリングで目をつけるべき場所

 初心者がリファクタリングで目をつけるべき場所

リファクタリングは重要ですが、初めて行う場合はどこから着手していいかわかりません。
この資料では、どういう点に着目すべきかという点を記載いたします。

04df7340898eac3a0536d3b47c55501c?s=128

kirimaru

June 24, 2020
Tweet

Transcript

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

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

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

  4. Code Smells に注目してみよう

  5. 話すこと / 話さないこと • リファクタリングをする際に注目す るところ • Code Smells •

    リファクタリングの重要性 • Design Pattern ◦ 私が良く知らない • やらないこと ◦ ライブコーディング 話すこと 話さないこと
  6. 対象者 / 非対象者 • リファクタリングをしたいけど、やり方 が分からない人 • 新卒~3年目くらいのエンジニア • 学生も含む

    • リファクタリングに興味がない人 • 新規機能の方が好きな人 対象者 非対象者
  7. HN:きり丸(きりちゃん)   本名:水上 皓登 Twitter:nainaistar ブログ:きり丸の日記 7 サーバーサイドエンジニア

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

  9. どちらがいいコード? if (true) { } if (true) { } if

    (hoge == true){ } if (hoge != false){ } if (きのこの山 > たけのこの里){ } if (たけのこの里 > きのこの山){ }
  10. いいコード  ≒  悪くないコード

  11. リファクタリングで勉強する優先度 • アンチパターン ◦ 問題を発見する • 見つける難易度は容易 • 修正も簡単 ◦

    IDEで自動修正できる可能性が ある • ★訓練がしやすい • グッドパターン ◦ 問題を解決する • 解決できれば影響が大きい • 難易度が高い • 覚えると銀の弾丸のように思えてし まって、パターンに振り回されることも ある Code Smells Design Pattern
  12. Code Smells の 一部抜粋 ★ Large Class ★ Long Method

    ★ Long Parameter ★ Duplicate Code ★ Magic Number ★ Comments ★ Arrow ★ Primitive Obsession ★ Feature Envy ★ Data Clumbs
  13. Large Class 例なし ※わかりやすいけど、 ここから始めるのは地獄 巨大なクラス。 責務が多すぎる可能性がある ので、責務ごとの分割できる可 能性あり。 仕方ないことも往々にしてあ

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

    に 記載してます
  15. Long Parameter public 学名 find学名( 界, 門, 亜門, 上綱, 綱

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

    ) または、共通項を見つけて、新 規のクラスにすることも有効。 ※主キー項目で一つのクラス にまとめるのはあり。 public 学名 find学名( 種別 ) public class 種別 { private 界 界; private 門 門; private 亜門 亜門; private 上綱 上綱; private 綱 綱; }
  17. 重複コード。 ただし、判断が難しい。 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) ?
  18. 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; } }
  19. Comments コメントが大量に 用いられている状態。 個人的にはJavaDocに書くのはOKだ が、JavaDoc嫌いな派閥もいる。 メソッドの責務が多すぎるときに 発生しがち。 例なし ※コメント書くなら意識したほ うがいい。

    コードには How テストコードには What コミットログには Why コードコメントには Why not
  20. 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; } ・・・ }
  21. ★ 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{}
  22. ★ Primitive Obsession List や Mapも対象。 単純なListではない限り、 同じListでも違う挙動をする可能性 があるので、別クラスにした方が良 い。

    通称:FCC (First Collection class) public class Duel{ List<Card> deck; // 山札 List<Card> trash; // 捨て札 List<Card> banish; // 除外 } public class Duel{ Deck deck; // 山札 Trash trash; // 捨て札 Banish banish; // 除外 } public class Deck{ List<Card> deck; } …
  23. ★ Feature Envy 別のクラスの値を使用して、処理し ている状態。 対象クラスの情報が流出してしまっ ている。 流出後の処理は追いづらく、リファ クタリングが困難になる。 public

    void Deck{ List<Card> deck; public Card searchMagicCard(){ for(Card card: deck){ String type = card.getType(); if (”magic”.equals(type)) return card; } } } public void Deck{ List<Card> deck; public Card searchMagicCard(){ for(Card card: deck){ if (card.isMagicCard()) return card; } } }
  24. ★ 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; }
  25. Code Smells の 一部抜粋 ★ Large Class ★ Long Method

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

    ★ Long Parameter ★ Duplicate Code ★ Magic Number ★ Comments ★ Arrow ★ ドメイン知識不足 ◦ Primitive Obsession ◦ Feature Envy ◦ Data Clumbs
  27. おわりに リファクタリングは、行おうとする意思が無ければ、 問題を見つける力は身につきません。 既存の構造を崩さないまま、 新規の構造に変更していくリファクタリングは、 設計そのものとも言えます。 設計は高度な仕事です。 ぜひ、Code Smellsから設計力を磨いていってください。

  28. Appendix

  29. 収まりきらなかった内容 • 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/

  30. 参考資料 および テンプレート • 使用テンプレート https://azusa3.sanographix.net/ • Code Smells https://refactoring.guru/refactoring/smells • 翻訳記事

    http://qiita.com/taumax/items/f192b16676f78fa04849
  31. 参考資料 および テンプレート • CSD研修 https://www.odd-e.jp/ja/service_csd/ • CSD研修の講師のかたの直近の登壇 Scrum fest Osaka 2020

    テスタビリティが低いシステムのためのテスティングテクニック -ライブコーディング https://confengine.com/scrum-fest-osaka-2020/proposal/14016/-