Slide 1

Slide 1 text

リファクタリングで実装が○○分短縮した話

Slide 2

Slide 2 text

自己紹介 ・千田健太郎 ・株式会社インフィニットループ ・2019年4月入社 ・WEBシステム開発やってます ・業務系Webアプリケーションの保守開発

Slide 3

Slide 3 text

リファクタリングとは

Slide 4

Slide 4 text

リファクタリングの定義 ・振る舞いは変えずに中身だけ変えること

Slide 5

Slide 5 text

リファクタリングを行う理由 ・ソフトウェアを理解しやすくする ・より速くプログラミングできる

Slide 6

Slide 6 text

リファクタリングをいつやるべきか ・コードに「不吉なにおい」を感じ始めたら ・機能追加の時にリファクタリングする

Slide 7

Slide 7 text

リファクタリングをすることになった経緯

Slide 8

Slide 8 text

リファクタリングをすることになった経緯 新規機能追加が控えていた ・どこに追加すればいいのかわからない ・どう動作確認すればいいのかわからない

Slide 9

Slide 9 text

リファクタリングをすることになった経緯 チームでのプロジェクト振り返りで問題認識していた  ・仕様がわからない  ・動作確認がわからない  ・Unitテストがつらい   など

Slide 10

Slide 10 text

リファクタリングをすることになった経緯 Unitテストが特につらかったらしい  ・網羅するのが大変  ・トライ&エラーでなんとか通していた  ・修正に数日かかっていたとか

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

対応方針

Slide 16

Slide 16 text

対応方針 1.最新の動作確認項目を作成  ・リファクタ前後で振る舞いに差が無いことを確認できない  ※Unitテストは問題なく動いていた

Slide 17

Slide 17 text

対応方針 2.Modelクラスの分割  ・サーバーサイドに焦点を絞り対応  ・処理は変えない

Slide 18

Slide 18 text

リファクタリング対象の画面

Slide 19

Slide 19 text

1つのModelに 5つの画面! リファクタリング対象の画面

Slide 20

Slide 20 text

対応したこと

Slide 21

Slide 21 text

1.最新の動作確認項目を作成 設計書をベースに作成  →不安なところはお客様に確認してもらった  →修正に問題がないことが確認できるようになった

Slide 22

Slide 22 text

2.Modelクラスの分割 メソッドが扱うデータの種類で抽出  ・画面初期表示するデータ、更新対象データなど

Slide 23

Slide 23 text

変更前

Slide 24

Slide 24 text

変更後

Slide 25

Slide 25 text

2.Modelクラスの分割 画面機能によって分割
  ・画面機能を5つ含むModelを、5つのクラスに分割
  ・このクラスでは基本的に共通処理を呼び出すだけにする
   →共通処理以外の記述が画面モード独自の処理と分かる
 
 


Slide 26

Slide 26 text

変更前

Slide 27

Slide 27 text

変更後

Slide 28

Slide 28 text

変更後 画面機能毎のModelに分割

Slide 29

Slide 29 text

2.Modelクラスの分割 分割したクラスが継承する抽象クラス作成
  ・各画面のメソッドを全て定義しておく
  ・利用する場合継承先でオーバーライドする
  ・オーバーライドせずに呼ばれたら例外を投げる
  →実装漏れや意図していない処理が呼ばれたら検知できるようになる


Slide 30

Slide 30 text

abstract class BaseModel { public function save(array $params) { throw new Exception('Undefined function called'); } public function delete(array $params) { throw new Exception('Undefined function called'); } } (例)抽象クラス

Slide 31

Slide 31 text

class Display1Model extends BaseModel { public function save(array $params) { // 何らかの処理 } // deleteメソッドは使わないのでオーバーライドしない } (例)画面機能1クラス deleteメソッドが呼ばれたら検知できるように!

Slide 32

Slide 32 text

2.Modelクラスの分割 画面機能を判定してインスタンスを返すFactoryクラス作成  ・画面機能の判定、インスタンス生成処理をまとめておく  →画面機能の判定について意識しない

Slide 33

Slide 33 text

変更前

Slide 34

Slide 34 text

完成

Slide 35

Slide 35 text

対応結果

Slide 36

Slide 36 text

対応結果 ・ほぼ想定していた通りに進めた ・動作確認項目とUnitテストで確認し、問題無く完了できた

Slide 37

Slide 37 text

対応してみて

Slide 38

Slide 38 text

自分にとって

Slide 39

Slide 39 text

対応してみて(自分にとって) 新規機能追加が捗った  ・設計をスムーズに行えた   →仕様を理解  ・実装がスムーズに行えた   →複雑度解消  ・Unitテストが1日かからずに直せた

Slide 40

Slide 40 text

リファクタリング前 どこを修正・・?

Slide 41

Slide 41 text

リファクタリング後 修正対象が明確に! この2画面が対象

Slide 42

Slide 42 text

対応してみて(自分にとって) 読みやすいコードを書こうと改めて思った ・今回みたいな機会はほぼ無い ・仕様理解のためにコードしか頼れない事がある ・自分のために

Slide 43

Slide 43 text

チームにとって

Slide 44

Slide 44 text

対応してみて(チームにとって) ・コードを触る心理的ハードルが下がった ・プロダクトの理解が深まった ・開発、リファクタの意識向上に繋がった

Slide 45

Slide 45 text

お客様にとって

Slide 46

Slide 46 text

対応してみて(お客様にとって) ・影響範囲が調査しやすくなった ・修正コストが減った(コード、Unitテスト)(ような気がする

Slide 47

Slide 47 text

まとめ

Slide 48

Slide 48 text

まとめ ・実装時間短縮された(はず ・実装時間短縮だけではなく、様々な改善に繋がる ・自分・チーム・お客様、つまりプロジェクト全体に良い影響がある

Slide 49

Slide 49 text

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