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

cocone Teck Talk Vol.1 - 大規模リファクタリング

cocone
August 17, 2021

cocone Teck Talk Vol.1 - 大規模リファクタリング

cocos2dx V2 から V3 への道のりとその先のMetalを見据えて
「大規模」リファクタリングでやっておくべきこと

cocone

August 17, 2021
Tweet

More Decks by cocone

Other Decks in Programming

Transcript

  1. 大規模リファクタリング

    岡田大介


    View Slide

  2. 自己紹介

    大規模リファクタリング 


    View Slide

  3. 職務経歴

    ・株式会社リコー (約10年)

    ・ココネ株式会社

    最近の技術経歴

    ・cocos2dx,Unity,ReactNative

    ・C++,C#,TypeScript

    最近の趣味

    ・卓球

    ・ゴーストオブツシマ

    ・JustDance


    岡田大介

    クライアント開発/ポケコロ開発リーダー 


    View Slide

  4. 大規模リファクタリングについて

    「やってよかったこと/やるべきこと」

    を中心に話します。


    View Slide

  5. は じ ま り/ 背 景

    大規模リファクタリング 


    View Slide

  6. はじまり

    ・10年ほど走ってきたスマホアプリで超スパゲッティコード

    え、100万行?? (ステップ数ではなく行数。。。とはいえ)


    ・何か機能を作るとすぐにどこか関係ない所でバグが出る。


    ・結果開発コストが弊社の他アプリと比べても1.5〜2倍はコストがかかる


    今の状況
    闇が深い


    View Slide

  7. はじまり

    ・10年ほど走ってきたスマホアプリで超スパゲッティコード

    え、100万行?? (ステップ数ではなく行数。。。とはいえ)


    ・何か機能を作るとすぐにどこか関係ない所でバグが出る。


    ・結果開発コストが弊社の他アプリと比べても1.5〜2倍はコストがかかる


    なんとかしたいと思いつつ、

    サービス最優先

    直そうとチャレンジしようとした人は

    なぜかいつも他の部署へ異動。。

    今の状況
    ビルド時間が長すぎ!! 

    技術力とは別のほぼ職人芸 

      影響度読めない

    闇

    闇が深い


    View Slide

  8. はじまり

    ・2018/6

    Apple、ios/macで

    グラフィックスAPI「OpenGL」非推奨を宣言


    Apple社の「Metal」への対応が必須へ



    View Slide

  9. はじまり

    cocos2dx version2ベース (cocosの最新は4でMetal対応されている)


    アイテム、UIに弊社独自のファイル形式を使用、描画処理にダイレクトにOpenGLを使
    用


    アプリの状況
    Metal対応するしかない!


    View Slide

  10. はじまり

    開発リーダーしつつ、Metal対応へ向けてリファクタリングも行うことに

    「このアプリの開発リーダーとMetalへの対応よろしくね」

    「はい。。。(まじか)」


    View Slide

  11. やるべきこと

    やってよかったこと

    大規模リファクタリング 


    View Slide

  12. やるべきこと/やってよかったこと 

    計画について    


    View Slide

  13. やるべきこと/やってよかったこと① 

    関係者へ理解を求めること

    関係者 = 事業の責任者(事業部長、社長、各職種リーダーなど)、CTO、サービスへの決定権を持つ人 

    リファクタリング「する」ことへのリスク 

    リファクタリング「しない」ことへのリスク 

    計画の共有


    このあたりをちゃんと説明すること 


    開発以外の人からも計画や 

    人員計画などのアイディアが出る 

    運用中のサービスの大規模リファクタリングとなると影響度が尋
    常じゃない!!

    が、やらないと将来的にまずい!!! 


    View Slide

  14. やるべきこと/やってよかったこと② 

    計画は絶えず見直す

    当初の計画

    年末から開発者全員(10人以上)でサービス開発を止めて 

    cocos2dxV2→cocos2dxV4(Metal)へ変更 4ヶ月 

    大きい

    計画変更

    cocos2dxV2→V3へ変更
    次の計画変更

    次の年の4月から
    次の次の計画

    サービス開発を止めずに対応
    次の次の次の計画

    対応メンバーは少数精鋭約4人で

    View Slide

  15. やるべきこと/やってよかったこと② 

    計画は絶えず見直す

    目標

    期間

    チーム体制


    全部見直しが必要 

    見直し項目
    特に期間は関係者への共有は必須 (いいづらいけども) 

    最初にとても見積もりきれない

    絶えず見直しと関係者への共有を忘れない

    場合によってはゴールの見直しも必要

    View Slide

  16. やるべきこと/やってよかったこと③ 

    目標をたてていくこと

    小さい

    ex.

    ・技術課題の管理

    ・TableViewの差し替え、37/149 達成など

    ・Popup画面の対応 50/85


    細かくタスクを管理し、達成具合を記載していくこと

    ・普通のプロジェクト以上に見える化が大事、周りから見ると何やってるか分からない

    ・モチベーションの持続  正直リファクタリングを長時間ひたらすらやるのはツライ

    View Slide

  17. やるべきこと/やってよかったこと④ 

    チーム体制

    リファクタリングということで中々別チームを作るのは難しいですが

    リファクタリングに集中できる環境を作ること

    ・チームをサービス側とリファクタリング側で分割

    ・互いにリーダーを立てた

    サービス開発を止めずに対応するということで。。

    リファクタリングリーダー(V3) 
 サービスリーダー(V2) 


    View Slide

  18. 開発について    


    View Slide

  19. やるべきこと/やってよかったこと⑤ 

    Debug機能の充実化/開発環境の充実化 

    ・ログ機能

    ・画面レイヤー構造の確認ツール

    ・アカウントの切り替え機能

    ・アバター確認

    ・UI確認機能

    ・Androidバックキー

    などなど

    マシンを差し替え

    ex.Rizen9マシンにしたらAndroidは2倍

    ex.M1Macもビルド時間の向上に

    ・バグは大量に出るので、原因究明できるようにしておく。今後の役にも立つ

    ・開発速度を早くする工夫。cocos2dxは。。

    ・ビルドマシンは状況によりけりですが、良くできるならすべき


    View Slide

  20. やるべきこと/やってよかったこと⑥ 

    断捨離 

    ・機能の削除


    ・ソースコード(クラス、関数)の削除


    対応箇所をいかに減らすか

    ビルド時間の向上にもつながる


    View Slide

  21. やるべきこと/やってよかったこと⑥ 

    常にマージ/最新の状態を保つこと 

    ・Gitで管理


    ・サービス側がリリースされる度にマージ


    ・一度乖離すると非常に難しい


    ・ソースコードは意外となんとかなる


    ・Xcodeのプロジェクトファイルが結構厄介 

    マージツールとしてmergepbxを使用

    XcodeGenも今後検討したいところ


    View Slide

  22. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    ・シングルトンの嵐

    ・依存関係がすごい

    ・SOLID原則に反しまくっている

    ・色々な所でベースのLayerクラスをdynamic_castして処理を判断している


    ・せめてプラットフォーム部分はinterfaceを分離。

    ・シングルトンではなくサービスロケータに。

    ・DI的にするのは中途半端に終わりさらなるカオスになりそうと判断

    ・画面遷移の仕組みも修正


    全部は直せない、何年かかるか分からん!!

    View Slide

  23. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    とりあえずinterfaceは分離しよう、
    具象クラスであるシングルトンも自然に減るだろう。。
    その上に変更もしていく
    CP1AssetManager
    CP2AssetManager
    IAssetManager
    Locator
    Singleton

    View Slide

  24. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    CP1AssetManager
    Singleton
    Client::funciton{
      CP1AssetManager::getInstance().download("main_asset");
    }

    View Slide

  25. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    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


    View Slide

  26. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    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なくす
    開発途中

    View Slide

  27. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    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

    View Slide

  28. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    BaseLayer
    +restoreMyAvatar()
    +nativeEventReceive()
    +block()
    +unblock()
    +onMovePlanet()
    +startAvatarIdleAction()
    +stopAvatarIdleAction()
    +show()
    ・・・
    Fatなクラス

    ベースのクラスの割に色々と機能が

    詰め込まれている状態


    View Slide

  29. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    BaseLayer
    +show()
    ・・・
    LayerAvatarInterface
    +restoreMyAvatar()
    +startAvatarIdleAction()
    +stopAvatarIdleAction()
    BlockInterface
    +block()
    +unblock()
    PlanetInterface
    +onMovePlanet
    まずはとにかく分割

    View Slide

  30. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    BaseLayer
    +show()
    ・・・
    LayerAvatarInterface
    +restoreMyAvatar()
    +startAvatarIdleAction()
    +stopAvatarIdleAction()
    BlockInterface
    +block()
    +unblock()
    PlanetInterface
    +onMovePlanet
    一部しか使っていないものは
    具象クラスの方へ移動
    PlanetLayer
    ・・・

    View Slide

  31. やるべきこと/やってよかったこと⑦ 

    テストできる設計を目指す 

    BaseLayer
    +show()
    ・・・
    LayerAvatarInterface
    +restoreMyAvatar()
    +startAvatarIdleAction()
    +stopAvatarIdleAction()
    BlockInterface
    +block()
    +unblock()
    PlanetInterface
    +onMovePlanet
    使わなくなったものは削除
    PlanetLayer
    ・・・

    View Slide

  32. やるべきこと/やってよかったこと⑧ 

    いじらせない 

    ・interface分離


     いっそのこと

    ・ライブラリ化 (モジュール化)

    ソースコードを書く以上だんだんおかしくなっていく


    View Slide

  33. まとめ

    大規模リファクタリング 


    View Slide

  34. 一番重要なこと

    ・大規模リファクタリングの場合、関係者への理解は必須



    痛感したこと

    ・最初からリファクタリングは定期的にしておくべき


    ・新規アプリで余裕なくても2年すぎたらやるべき

    #2年すぎてサービスが続いているならば、まだサービスは続くと思うので


    ・プラットフォームは定期的にバージョンアップすべき(cocosにしろunityにしろndkでも)

    まとめ


    View Slide

  35. Q & A


    View Slide

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


    View Slide