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

リファクタリングいつやるの? 〜依存の整理〜

リファクタリングいつやるの? 〜依存の整理〜

2025/04/08(火) 「バックエンドTypeScript勉強会 ~Macbee Planet x レバレジーズの事例大公開~」での登壇スライドです。
https://teratail.connpass.com/event/348281/

Tech Leverages

April 08, 2025
Tweet

More Decks by Tech Leverages

Other Decks in Technology

Transcript

  1. | © 2024 Levtech Co., Ltd. 3 レバテック開発部 大内 瑠馬  オオウチ

      リュウマ # うどん # ラーメン # ライブ # ゴルフ  # ポケポケ
  2. | © 2024 Levtech Co., Ltd. 4 レバテックルーキー https://rookie.levtech.jp/ 新卒向けスカウトサービス 最近学生が自分たちから

    企業に応募できる機能も リリースしました 普段こんなサービスを開発・保守してます リファクタリングいつやるの?
  3. | © 2024 Levtech Co., Ltd. 6 • バックエンドの方 • リファクタリングをしたいけど、時間がなくてできない方

    • なんか面白そうと思った方 今日の内容を届けたい方 リファクタリングいつやるの?
  4. | © 2024 Levtech Co., Ltd. 7 今日触れないこと • 具体的なライブラリやフレームワークの内容について 注意書き

    • 発表する内容はまだ進行段階のため、一部理想をふくみます 今日触れないこと & 注意書き リファクタリングいつやるの?
  5. | © 2024 Levtech Co., Ltd. 9 TypeORMを使用していて、 • 型安全ではないことに気づく •

    リレーションの取得で性能が劣化するパターンがあることに気づく • クエリビルダー見づらい このことからPrismaへの移行を検討し始めた。 (最近は他の選択肢も出始めてますが、ここでは割愛します) ことの発端 リファクタリングいつやるの?
  6. | © 2024 Levtech Co., Ltd. 11 移行しようと思ったが、サービスがTypeORMに依存 ことの発端 リファクタリングいつやるの? @Injectable()

    export class HogeService implements ApplicationService<HogeRequest, HogeResponse> { constructor( @InjectRepository(Hoge) private readonly HogeRepository: Repository<Hoge>, ) {} async handle(request: HogeRequest): Promise<HogeResponse> { return await this.HogeRepository.findOne({ id: request.id }); } }
  7. | © 2024 Levtech Co., Ltd. 12 移行しようと思ったが、サービスがTypeORMに依存 => Application層がガッツリORMに依存している =>

    移行時の検証のコストが高いので、なるべく小さくしたい => 小さくするには、影響範囲を限定する必要がある => 依存整理が必要 => リファクタリングをしよう! ことの発端 リファクタリングいつやるの?
  8. | © 2024 Levtech Co., Ltd. 14 なにをしたのか 前提:レバテックルーキーのシステムのアーキテクチャ • ディレクトリ構成

    ◦ application(主にサービスクラス) ◦ infrastructure(grpcやgraphqlのエンドポイントが定義) ◦ entity(TypeORMのentity群) • ヘキサゴナルアーキテクチャを採用している ◦ ただ、開発時の納期的な事情もあり、中途半端な状態になっている ◦ TypeORMのentityもinfrastructureにあるべきであると思ってる.. リファクタリングいつやるの?
  9. | © 2024 Levtech Co., Ltd. 21 なにをしたのか(依存の整理) リファクタリングいつやるの? Service TypeORM

    Repository Application Infrastructure Repository Interface Entity Prisma(仮) Repository
  10. | © 2024 Levtech Co., Ltd. 23 なにをしたのか(依存の整理) リファクタリングいつやるの? 依存整理を進める上で、TypeORMが提供しているRepositoryの機能と名 前が被ってしまう問題が発生した。

    (Repositoryの中でRepositoryというメンバ変数を呼ぶ不思議な実装) 大きな問題があるわけではないが、 わかりづらい実装になってしまうので、 解決したい。 export class HogeRepositoryImpl implements HogeRepositoryInterface { constructor( private readonly hogeRepository: Repository<Hoge> ) {} async findById(id: number): Promise<Hoge | null> { return this.hogeRepository.findOne({ where: { id } }); } }
  11. | © 2024 Levtech Co., Ltd. 24 なにをしたのか(依存の整理) リファクタリングいつやるの? 依存整理を進める上で、TypeORMが提供しているRepositoryの機能と名 前が被ってしまう問題が発生した。

    (Repositoryの中でRepositoryというメンバ変数を呼ぶ不思議な実装) 大きな問題があるわけではないが、 わかりづらい実装になってしまうので、 解決したい。 => EntityをActiveRecordにして、 Repositoryを使用しないようにした (BaseEntityを継承するとARになる) @Entity() export class Hoge extends BaseEntity { // ここにカラム記載 } export class HogeRepositoryImpl implements HogeRepositoryInterface { async findById(id: number): Promise<Hoge | null> { return Hoge.findOne({ where: { id } }); } }
  12. | © 2024 Levtech Co., Ltd. 25 依存整理をしたことで以下のメリットが生まれた • ORMなどデータベースとの接続方法の変更の影響をRepositoryに限定できる ◦

    修正範囲がはっきりするので検証も楽 • ユニットテストを書く準備をすることができた ◦ サービスのユニットテストを書くにしても、TypeORMが存在していたため、結合テストで動作を担保す るしかなかったが、Repositoryをモックすればよくなった => 安全に移行する準備をすることができた なにをしたのか リファクタリングいつやるの?
  13. | © 2024 Levtech Co., Ltd. 28 “リファクタリングとは、外部の振る舞いを保ったままで、 内部の構造を改善していく作業 を指します” “新たな機能を追加する必要があり、現状の設計が

    その変更にうまく適応できていない場合には、 リファクタリングを最初に行なってしまい、その後で 追加機能を開発した方が早い のです” どう進めているのか リファクタリングいつやるの?
  14. | © 2024 Levtech Co., Ltd. 30 “リファクタリングとは、外部の振る舞いを保ったままで、 内部の構造を改善していく作業 を指します” =>

    見た目や機能は何も変えずに中身だけよくする = 既存機能に影響はない (ようにする) どう進めているのか リファクタリングいつやるの?
  15. | © 2024 Levtech Co., Ltd. 32 どう進めているのか リファクタリングいつやるの? “新たな機能を追加する必要があり、現状の設計が その変更にうまく適応できていない場合には、

    リファクタリングを最初に行なってしまい、その後で 追加機能を開発した方が早い のです” => 機能開発の前にサッとやってしまうのがいい
  16. | © 2024 Levtech Co., Ltd. 33 どう進めているのか リファクタリングいつやるの? 先人の教え通りに機能開発前にリファクタリングを実施 メリットとしては、

    • 機能開発前にリファクタリングすることで、コードを整理した後に機 能開発に入れるので修正範囲が明確 • 機能開発のついでにリファクタリングすることで、変更が入りやす い機能のコードにリファクタリングを適用できる
  17. | © 2024 Levtech Co., Ltd. 35 どう進めているのか リファクタリングいつやるの? デメリットもあった =>

    そのタスクの開発速度がおちる • サービスとリポジトリの分割(またはクエリサービス) • 上記に伴うテストコードの追加 ◦ AIがあるだけまだましだが、それでも工数はかかる • スプリントのベロシティに影響が....
  18. | © 2024 Levtech Co., Ltd. 36 どう進めているのか リファクタリングいつやるの? デメリットもあった =>

    そのタスクの開発速度がおちる • サービスとリポジトリの分割(またはクエリサービス) • 上記に伴うテストコードの追加 ◦ AIがあるだけまだましだが、それでも工数はかかる • スプリントのベロシティに影響が ....
  19. | © 2024 Levtech Co., Ltd. 37 どう進めているのか リファクタリングいつやるの? “ソフトウェア開発でリファクタリングを行うときには、作業を二つの活動に区分すべ きです。すなわち、機能追加とリファクタリングを区別するのです”

    “ソフトウェアを開発している時、私は二つの帽子を頻繁に被り直しています。新た な機能を追加しようとしているとコードの構造を少し変えれば簡単に機能追加でき ることに気づきます。そこでリファクタリングの帽子を被り直します。コードの構造が よくなったところで、また帽子を替えて機能開発を始めます” => こんな器用なことはできないので、タスクを分けてしまえばいい
  20. | © 2024 Levtech Co., Ltd. 40 どう進めているのか リファクタリングいつやるの? プランニング時にタスクとして計上することで メリットとして、

    • ベロシティのブレの改善 • 合法的にリファクタリングができる(大事) => 事業側は問題ないか?
  21. | © 2024 Levtech Co., Ltd. 41 どう進めているのか リファクタリングいつやるの? “管理者や顧客によっては、コードの健康状態が生産性にどれだけ影響を与える のか、技術的に認識できないこともあるでしょう。そうした時に、いささか問題発言

    的なアドバイスをしておきます。「彼らには黙ってリファクタリングする 」です” “スケジュールを気にする管理者であれば、開発者が最も速い方法を選択するの を望むでしょう。どのような手段で実施するかは開発者側の責任 です。新たな機 能を素早く提供できる技能を買われているのですし、 そのための手段がリファクタリングなのです。”
  22. | © 2024 Levtech Co., Ltd. 42 どう進めているのか リファクタリングいつやるの? レバテックルーキーの開発チームでは? 事業側からは完了要件やデザインをもらう

    => その後の実装をどう行うか、どう実現するかはエンジニアの範囲 詳細設計や実装の設計、シナリオテストなどをスプリント中に設計タスクとして実施 し、メンバーでレビューを行う 次のスプリントでタスクを実施する(この繰り返し)
  23. | © 2024 Levtech Co., Ltd. 43 どう進めているのか リファクタリングいつやるの? レバテックルーキーの開発チームでは? 事業側からは完了要件やデザインをもらう

    => その後の実装をどう行うか、どう実現するかはエンジニアの範囲 詳細設計やサブタスク作成、シナリオテスト設計などをスプリント中に設計タスクと して実施し、開発メンバーでレビューを行う 次のスプリントでタスクを実施する(この繰り返し) => 詳細設計時に、サブタスクとしてリファクタリングタスクを切る
  24. | © 2024 Levtech Co., Ltd. 46 どう進めているのか( きをつけたこと) リファクタリングいつやるの? 大前提:リファクタリングは開発の速度を速めるために行う

    • テストコードは必ずリファクタの前に書くこと ◦ 理由:機能を変えずに内部を変えることがリファクタなので、担保できる仕組みを用意する ▪ デグレが発生したりするとかえって工数がかかってしまう ◦ すでにテストコードがあるなら問題なし( Integrationだけとかでも可) • タスク単位でレビューをすること ◦ 理由:単純にレビュアーが大変 ▪ レビュー中のコンテキストスイッチが単純にしんどいし工数がかかってしまう ◦ リファクタリングが終わった段階でレビュータスクを入れてレビューする
  25. | © 2024 Levtech Co., Ltd. 48 最後に(まとめ) リファクタリングいつやるの? • DIPによって依存関係を整理することで、安全なリファクタリングをする準備がで

    きる ◦ 修正時の影響範囲を小さくすることができる ◦ ユニットテストを書けるようになる • リファクタリングは機能改修前にやってしまう ◦ 結果的にその方が開発が速くなる ◦ ただし、リファクタリングをする前にまずはテストを準備すること • リファクタリングはタスクを切って行う ◦ 機能開発をどう行うかはエンジニアの責任範囲 ◦ それで開発が早くなるなら積極的にタスクを切る