Slide 1

Slide 1 text

大規模リファクタリング
 岡田大介


Slide 2

Slide 2 text

自己紹介
 大規模リファクタリング 


Slide 3

Slide 3 text

職務経歴
 ・株式会社リコー (約10年)
 ・ココネ株式会社
 最近の技術経歴
 ・cocos2dx,Unity,ReactNative
 ・C++,C#,TypeScript
 最近の趣味
 ・卓球
 ・ゴーストオブツシマ
 ・JustDance
 
 岡田大介
 クライアント開発/ポケコロ開発リーダー 


Slide 4

Slide 4 text

大規模リファクタリングについて
 「やってよかったこと/やるべきこと」
 を中心に話します。
 


Slide 5

Slide 5 text

は じ ま り/ 背 景
 大規模リファクタリング 


Slide 6

Slide 6 text

はじまり
 ・10年ほど走ってきたスマホアプリで超スパゲッティコード
 え、100万行?? (ステップ数ではなく行数。。。とはいえ)
 
 ・何か機能を作るとすぐにどこか関係ない所でバグが出る。
 
 ・結果開発コストが弊社の他アプリと比べても1.5〜2倍はコストがかかる
 
 今の状況 闇が深い


Slide 7

Slide 7 text

はじまり
 ・10年ほど走ってきたスマホアプリで超スパゲッティコード
 え、100万行?? (ステップ数ではなく行数。。。とはいえ)
 
 ・何か機能を作るとすぐにどこか関係ない所でバグが出る。
 
 ・結果開発コストが弊社の他アプリと比べても1.5〜2倍はコストがかかる
 
 なんとかしたいと思いつつ、
 サービス最優先
 直そうとチャレンジしようとした人は 
 なぜかいつも他の部署へ異動。。 
 今の状況 ビルド時間が長すぎ!! 
 技術力とは別のほぼ職人芸 
   影響度読めない
 闇
 闇が深い


Slide 8

Slide 8 text

はじまり
 ・2018/6
 Apple、ios/macで
 グラフィックスAPI「OpenGL」非推奨を宣言
 
 Apple社の「Metal」への対応が必須へ
 
 


Slide 9

Slide 9 text

はじまり
 cocos2dx version2ベース (cocosの最新は4でMetal対応されている)
 
 アイテム、UIに弊社独自のファイル形式を使用、描画処理にダイレクトにOpenGLを使 用
 
 アプリの状況 Metal対応するしかない!


Slide 10

Slide 10 text

はじまり
 開発リーダーしつつ、Metal対応へ向けてリファクタリングも行うことに
 「このアプリの開発リーダーとMetalへの対応よろしくね」
 「はい。。。(まじか)」


Slide 11

Slide 11 text

やるべきこと
 やってよかったこと
 大規模リファクタリング 


Slide 12

Slide 12 text

やるべきこと/やってよかったこと 
 計画について    


Slide 13

Slide 13 text

やるべきこと/やってよかったこと① 
 関係者へ理解を求めること
 関係者 = 事業の責任者(事業部長、社長、各職種リーダーなど)、CTO、サービスへの決定権を持つ人 
 リファクタリング「する」ことへのリスク 
 リファクタリング「しない」ことへのリスク 
 計画の共有
 
 このあたりをちゃんと説明すること 
 
 開発以外の人からも計画や 
 人員計画などのアイディアが出る 
 運用中のサービスの大規模リファクタリングとなると影響度が尋 常じゃない!!
 が、やらないと将来的にまずい!!! 


Slide 14

Slide 14 text

やるべきこと/やってよかったこと② 
 計画は絶えず見直す
 当初の計画
 年末から開発者全員(10人以上)でサービス開発を止めて 
 cocos2dxV2→cocos2dxV4(Metal)へ変更 4ヶ月 
 大きい
 計画変更
 cocos2dxV2→V3へ変更 次の計画変更
 次の年の4月から 次の次の計画
 サービス開発を止めずに対応 次の次の次の計画
 対応メンバーは少数精鋭約4人で

Slide 15

Slide 15 text

やるべきこと/やってよかったこと② 
 計画は絶えず見直す
 目標
 期間
 チーム体制
 
 全部見直しが必要 
 見直し項目 特に期間は関係者への共有は必須 (いいづらいけども)  
 最初にとても見積もりきれない
 絶えず見直しと関係者への共有を忘れない
 場合によってはゴールの見直しも必要 


Slide 16

Slide 16 text

やるべきこと/やってよかったこと③ 
 目標をたてていくこと
 小さい
 ex.
 ・技術課題の管理
 ・TableViewの差し替え、37/149 達成など
 ・Popup画面の対応 50/85
 
 細かくタスクを管理し、達成具合を記載していくこと
 ・普通のプロジェクト以上に見える化が大事、周りから見ると何やってるか分からない 
 ・モチベーションの持続  正直リファクタリングを長時間ひたらすらやるのはツライ 


Slide 17

Slide 17 text

やるべきこと/やってよかったこと④ 
 チーム体制
 リファクタリングということで中々別チームを作るのは難しいですが
 リファクタリングに集中できる環境を作ること
 ・チームをサービス側とリファクタリング側で分割
 ・互いにリーダーを立てた
 サービス開発を止めずに対応するということで。。
 リファクタリングリーダー(V3) 
 サービスリーダー(V2) 


Slide 18

Slide 18 text

開発について    


Slide 19

Slide 19 text

やるべきこと/やってよかったこと⑤ 
 Debug機能の充実化/開発環境の充実化 
 ・ログ機能
 ・画面レイヤー構造の確認ツール 
 ・アカウントの切り替え機能
 ・アバター確認
 ・UI確認機能
 ・Androidバックキー
 などなど
 マシンを差し替え
 ex.Rizen9マシンにしたらAndroidは2倍
 ex.M1Macもビルド時間の向上に
 ・バグは大量に出るので、原因究明できるようにしておく。今後の役にも立つ
 ・開発速度を早くする工夫。cocos2dxは。。
 ・ビルドマシンは状況によりけりですが、良くできるならすべき


Slide 20

Slide 20 text

やるべきこと/やってよかったこと⑥ 
 断捨離 
 ・機能の削除
 
 ・ソースコード(クラス、関数)の削除 
 
 対応箇所をいかに減らすか
 ビルド時間の向上にもつながる


Slide 21

Slide 21 text

やるべきこと/やってよかったこと⑥ 
 常にマージ/最新の状態を保つこと 
 ・Gitで管理
 
 ・サービス側がリリースされる度にマージ 
 
 ・一度乖離すると非常に難しい
 
 ・ソースコードは意外となんとかなる 
 
 ・Xcodeのプロジェクトファイルが結構厄介 
 マージツールとしてmergepbxを使用 
 XcodeGenも今後検討したいところ 
 


Slide 22

Slide 22 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 ・シングルトンの嵐
 ・依存関係がすごい
 ・SOLID原則に反しまくっている
 ・色々な所でベースのLayerクラスをdynamic_castして処理を判断している
 
 ・せめてプラットフォーム部分はinterfaceを分離。
 ・シングルトンではなくサービスロケータに。
 ・DI的にするのは中途半端に終わりさらなるカオスになりそうと判断
 ・画面遷移の仕組みも修正
 
 全部は直せない、何年かかるか分からん!! 


Slide 23

Slide 23 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 とりあえずinterfaceは分離しよう、 具象クラスであるシングルトンも自然に減るだろう。。 その上に変更もしていく CP1AssetManager CP2AssetManager IAssetManager Locator Singleton

Slide 24

Slide 24 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 CP1AssetManager Singleton Client::funciton{   CP1AssetManager::getInstance().download("main_asset"); }

Slide 25

Slide 25 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 CP1AssetManager IAssetManager Locator Singleton 注入 Client::funciton{   CPLocator::AssetManager()->donwload("main_asset"); } Init {   IAssetManager assetManager = CP1AssetManager::getInstance()   CPLocator::provide(assetManager ); } 開発途中ではシングルトン状態とサービスロケータ を同居 Client2::funciton{   CP1AssetManager::getInstance().download("main_asset"); } 開発途中 利用者1
 利用者2


Slide 26

Slide 26 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 CP1AssetManager IAssetManager Locator Singleton 注入 Client::funciton{   CPLocator::AssetManager()->donwload("main_asset"); } Init {   IAssetManager assetManager = new CP1AssetManager()        CPLocator::provide(assetManager ); } Client2::funciton{   CPLocator::AssetManager()->donwload("main_asset"); } 全部置き換えたらSingletonなくす 開発途中

Slide 27

Slide 27 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 CP2AssetManager IAssetManager Locator 注入 Client::funciton{   CPLocator::AssetManager()->donwload("main_asset"); } Init {   IAssetManager assetManager = new CP2AssetManager()        CPLocator::provide(assetManager ); } Client2::funciton{   CPLocator::AssetManager()->donwload("main_asset"); } CP1AssetManager(cocosv2用)を CP2AssetManager(cocosV3用)に差し替え CP1AssetManager

Slide 28

Slide 28 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 BaseLayer +restoreMyAvatar() +nativeEventReceive() +block() +unblock() +onMovePlanet() +startAvatarIdleAction() +stopAvatarIdleAction() +show() ・・・ Fatなクラス
 ベースのクラスの割に色々と機能が
 詰め込まれている状態


Slide 29

Slide 29 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 BaseLayer +show() ・・・ LayerAvatarInterface +restoreMyAvatar() +startAvatarIdleAction() +stopAvatarIdleAction() BlockInterface +block() +unblock() PlanetInterface +onMovePlanet まずはとにかく分割

Slide 30

Slide 30 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 BaseLayer +show() ・・・ LayerAvatarInterface +restoreMyAvatar() +startAvatarIdleAction() +stopAvatarIdleAction() BlockInterface +block() +unblock() PlanetInterface +onMovePlanet 一部しか使っていないものは 具象クラスの方へ移動 PlanetLayer ・・・

Slide 31

Slide 31 text

やるべきこと/やってよかったこと⑦ 
 テストできる設計を目指す 
 BaseLayer +show() ・・・ LayerAvatarInterface +restoreMyAvatar() +startAvatarIdleAction() +stopAvatarIdleAction() BlockInterface +block() +unblock() PlanetInterface +onMovePlanet 使わなくなったものは削除 PlanetLayer ・・・

Slide 32

Slide 32 text

やるべきこと/やってよかったこと⑧ 
 いじらせない 
 ・interface分離
 
  いっそのこと
 ・ライブラリ化 (モジュール化)
 ソースコードを書く以上だんだんおかしくなっていく


Slide 33

Slide 33 text

まとめ
 大規模リファクタリング 


Slide 34

Slide 34 text

一番重要なこと
 ・大規模リファクタリングの場合、関係者への理解は必須
 
 
 痛感したこと
 ・最初からリファクタリングは定期的にしておくべき
 
 ・新規アプリで余裕なくても2年すぎたらやるべき
 #2年すぎてサービスが続いているならば、まだサービスは続くと思うので
 
 ・プラットフォームは定期的にバージョンアップすべき(cocosにしろunityにしろndkでも)
 まとめ


Slide 35

Slide 35 text

Q & A


Slide 36

Slide 36 text

ご静聴ありがとうございました!!