$30 off During Our Annual Pro Sale. View Details »

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

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

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

kirimaru

June 24, 2020
Tweet

More Decks by kirimaru

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  15. Long Parameter
    public 学名 find学名(
    界,
    門,
    亜門,
    上綱,

    )
    パラメータが3つ、4つ以上のメ
    ソッド。
    Interfaceで必要なパラメータ
    のみを露出させることで、使用
    するときはシンプルにできる。
    public 学名 find学名(

    ) {
    this.find学名(
    界, null, null, null, null
    );
    }
    ・・・

    View Slide

  16. Long Parameter
    public 学名 find学名(
    界,
    門,
    亜門,
    上綱,

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

    View Slide

  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)
    ?

    View Slide

  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;
    }
    }

    View Slide

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

    View Slide

  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;
    }
    ・・・
    }

    View Slide


  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{}

    View Slide


  22. 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;
    }

    View Slide


  23. 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;
    }
    }
    }

    View Slide


  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;
    }

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  28. Appendix

    View Slide

  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/

    View Slide

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

    View Slide

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

    View Slide