Slide 1

Slide 1 text

リファクタリングいつやるの? レバテック開発部 大内瑠馬 〜依存の整理〜

Slide 2

Slide 2 text

一番お伝えしたいこと リファクタリングを止めるな 機能改修を止めるな 今でしょ

Slide 3

Slide 3 text

| © 2024 Levtech Co., Ltd. 3 レバテック開発部 大内 瑠馬  オオウチ   リュウマ # うどん # ラーメン # ライブ # ゴルフ  # ポケポケ

Slide 4

Slide 4 text

| © 2024 Levtech Co., Ltd. 4 レバテックルーキー https://rookie.levtech.jp/ 新卒向けスカウトサービス 最近学生が自分たちから 企業に応募できる機能も リリースしました 普段こんなサービスを開発・保守してます リファクタリングいつやるの?

Slide 5

Slide 5 text

| © 2024 Levtech Co., Ltd. 5 backendのサービスの技術スタック、開発手法 リファクタリングいつやるの?

Slide 6

Slide 6 text

| © 2024 Levtech Co., Ltd. 6 ● バックエンドの方 ● リファクタリングをしたいけど、時間がなくてできない方 ● なんか面白そうと思った方 今日の内容を届けたい方 リファクタリングいつやるの?

Slide 7

Slide 7 text

| © 2024 Levtech Co., Ltd. 7 今日触れないこと ● 具体的なライブラリやフレームワークの内容について 注意書き ● 発表する内容はまだ進行段階のため、一部理想をふくみます 今日触れないこと & 注意書き リファクタリングいつやるの?

Slide 8

Slide 8 text

ことの発端

Slide 9

Slide 9 text

| © 2024 Levtech Co., Ltd. 9 TypeORMを使用していて、 ● 型安全ではないことに気づく ● リレーションの取得で性能が劣化するパターンがあることに気づく ● クエリビルダー見づらい このことからPrismaへの移行を検討し始めた。 (最近は他の選択肢も出始めてますが、ここでは割愛します) ことの発端 リファクタリングいつやるの?

Slide 10

Slide 10 text

| © 2024 Levtech Co., Ltd. 10 ことの発端 GeminiにPrismaとTypeORMの メリデメをまとめさせたが、 目的に沿ったものになっていそう。 リファクタリングいつやるの?

Slide 11

Slide 11 text

| © 2024 Levtech Co., Ltd. 11 移行しようと思ったが、サービスがTypeORMに依存 ことの発端 リファクタリングいつやるの? @Injectable() export class HogeService implements ApplicationService { constructor( @InjectRepository(Hoge) private readonly HogeRepository: Repository, ) {} async handle(request: HogeRequest): Promise { return await this.HogeRepository.findOne({ id: request.id }); } }

Slide 12

Slide 12 text

| © 2024 Levtech Co., Ltd. 12 移行しようと思ったが、サービスがTypeORMに依存 => Application層がガッツリORMに依存している => 移行時の検証のコストが高いので、なるべく小さくしたい => 小さくするには、影響範囲を限定する必要がある => 依存整理が必要 => リファクタリングをしよう! ことの発端 リファクタリングいつやるの?

Slide 13

Slide 13 text

なにをしたのか

Slide 14

Slide 14 text

| © 2024 Levtech Co., Ltd. 14 なにをしたのか 前提:レバテックルーキーのシステムのアーキテクチャ ● ディレクトリ構成 ○ application(主にサービスクラス) ○ infrastructure(grpcやgraphqlのエンドポイントが定義) ○ entity(TypeORMのentity群) ● ヘキサゴナルアーキテクチャを採用している ○ ただ、開発時の納期的な事情もあり、中途半端な状態になっている ○ TypeORMのentityもinfrastructureにあるべきであると思ってる.. リファクタリングいつやるの?

Slide 15

Slide 15 text

| © 2024 Levtech Co., Ltd. 15 ● サービスクラスのライブラリへの依存をやめさせる ○ DIP(依存性逆転の法則)を使用した依存の整理 ● ライブラリ移行(理想) なにをしたのか リファクタリングいつやるの?

Slide 16

Slide 16 text

| © 2024 Levtech Co., Ltd. 16 ● サービスクラスのライブラリへの依存をやめさせる ○ DIP(依存性逆転の法則)を使用した依存の整理 ● ライブラリ移行(理想) なにをしたのか リファクタリングいつやるの?

Slide 17

Slide 17 text

| © 2024 Levtech Co., Ltd. 17 なにをしたのか(依存の整理) リファクタリングいつやるの? Service TypeORM Application Entity

Slide 18

Slide 18 text

| © 2024 Levtech Co., Ltd. 18 なにをしたのか(依存の整理) リファクタリングいつやるの? Service TypeORM Repository Application Infrastructure Entity

Slide 19

Slide 19 text

| © 2024 Levtech Co., Ltd. 19 なにをしたのか(依存の整理) リファクタリングいつやるの? Service TypeORM Repository Application Infrastructure Repository Interface Entity

Slide 20

Slide 20 text

| © 2024 Levtech Co., Ltd. 20 なにをしたのか(依存の整理) リファクタリングいつやるの? Service TypeORM Repository Application Infrastructure Repository Interface Entity

Slide 21

Slide 21 text

| © 2024 Levtech Co., Ltd. 21 なにをしたのか(依存の整理) リファクタリングいつやるの? Service TypeORM Repository Application Infrastructure Repository Interface Entity Prisma(仮) Repository

Slide 22

Slide 22 text

| © 2024 Levtech Co., Ltd. 22 なにをしたのか(依存の整理) リファクタリングいつやるの? Service Prisma(仮) Repository Application Infrastructure Repository Interface Entity

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

| © 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 { return Hoge.findOne({ where: { id } }); } }

Slide 25

Slide 25 text

| © 2024 Levtech Co., Ltd. 25 依存整理をしたことで以下のメリットが生まれた ● ORMなどデータベースとの接続方法の変更の影響をRepositoryに限定できる ○ 修正範囲がはっきりするので検証も楽 ● ユニットテストを書く準備をすることができた ○ サービスのユニットテストを書くにしても、TypeORMが存在していたため、結合テストで動作を担保す るしかなかったが、Repositoryをモックすればよくなった => 安全に移行する準備をすることができた なにをしたのか リファクタリングいつやるの?

Slide 26

Slide 26 text

どう進めているのか

Slide 27

Slide 27 text

| © 2024 Levtech Co., Ltd. 27 先人に習います どう進めているのか リファクタリングいつやるの?

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

| © 2024 Levtech Co., Ltd. 29 “リファクタリングとは、外部の振る舞いを保ったままで、 内部の構造を改善していく作業 を指します” どう進めているのか リファクタリングいつやるの?

Slide 30

Slide 30 text

| © 2024 Levtech Co., Ltd. 30 “リファクタリングとは、外部の振る舞いを保ったままで、 内部の構造を改善していく作業 を指します” => 見た目や機能は何も変えずに中身だけよくする = 既存機能に影響はない (ようにする) どう進めているのか リファクタリングいつやるの?

Slide 31

Slide 31 text

| © 2024 Levtech Co., Ltd. 31 どう進めているのか リファクタリングいつやるの? “新たな機能を追加する必要があり、現状の設計が その変更にうまく適応できていない場合には、 リファクタリングを最初に行なってしまい、その後で 追加機能を開発した方が早い のです”

Slide 32

Slide 32 text

| © 2024 Levtech Co., Ltd. 32 どう進めているのか リファクタリングいつやるの? “新たな機能を追加する必要があり、現状の設計が その変更にうまく適応できていない場合には、 リファクタリングを最初に行なってしまい、その後で 追加機能を開発した方が早い のです” => 機能開発の前にサッとやってしまうのがいい

Slide 33

Slide 33 text

| © 2024 Levtech Co., Ltd. 33 どう進めているのか リファクタリングいつやるの? 先人の教え通りに機能開発前にリファクタリングを実施 メリットとしては、 ● 機能開発前にリファクタリングすることで、コードを整理した後に機 能開発に入れるので修正範囲が明確 ● 機能開発のついでにリファクタリングすることで、変更が入りやす い機能のコードにリファクタリングを適用できる

Slide 34

Slide 34 text

| © 2024 Levtech Co., Ltd. 34 どう進めているのか リファクタリングいつやるの? デメリットもあった

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

| © 2024 Levtech Co., Ltd. 38 どう進めているのか リファクタリングいつやるの? ベロシティに影響がある、遅くなることがわかっているなら 初めからタスクを分けて工数を計上 すればいいじゃない => プランニング時に SPを振って1つのタスクとして扱う

Slide 39

Slide 39 text

| © 2024 Levtech Co., Ltd. 39 どう進めているのか リファクタリングいつやるの? プランニング時にタスクとして計上することで メリットとして、 ● ベロシティのブレの改善 ● 合法的にリファクタリングができる(大事)

Slide 40

Slide 40 text

| © 2024 Levtech Co., Ltd. 40 どう進めているのか リファクタリングいつやるの? プランニング時にタスクとして計上することで メリットとして、 ● ベロシティのブレの改善 ● 合法的にリファクタリングができる(大事) => 事業側は問題ないか?

Slide 41

Slide 41 text

| © 2024 Levtech Co., Ltd. 41 どう進めているのか リファクタリングいつやるの? “管理者や顧客によっては、コードの健康状態が生産性にどれだけ影響を与える のか、技術的に認識できないこともあるでしょう。そうした時に、いささか問題発言 的なアドバイスをしておきます。「彼らには黙ってリファクタリングする 」です” “スケジュールを気にする管理者であれば、開発者が最も速い方法を選択するの を望むでしょう。どのような手段で実施するかは開発者側の責任 です。新たな機 能を素早く提供できる技能を買われているのですし、 そのための手段がリファクタリングなのです。”

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

| © 2024 Levtech Co., Ltd. 44 どう進めているのか リファクタリングいつやるの? 機能開発を進めながら リファクタリングを行うことができている

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

| © 2024 Levtech Co., Ltd. 46 どう進めているのか( きをつけたこと) リファクタリングいつやるの? 大前提:リファクタリングは開発の速度を速めるために行う ● テストコードは必ずリファクタの前に書くこと ○ 理由:機能を変えずに内部を変えることがリファクタなので、担保できる仕組みを用意する ■ デグレが発生したりするとかえって工数がかかってしまう ○ すでにテストコードがあるなら問題なし( Integrationだけとかでも可) ● タスク単位でレビューをすること ○ 理由:単純にレビュアーが大変 ■ レビュー中のコンテキストスイッチが単純にしんどいし工数がかかってしまう ○ リファクタリングが終わった段階でレビュータスクを入れてレビューする

Slide 47

Slide 47 text

最後に

Slide 48

Slide 48 text

| © 2024 Levtech Co., Ltd. 48 最後に(まとめ) リファクタリングいつやるの? ● DIPによって依存関係を整理することで、安全なリファクタリングをする準備がで きる ○ 修正時の影響範囲を小さくすることができる ○ ユニットテストを書けるようになる ● リファクタリングは機能改修前にやってしまう ○ 結果的にその方が開発が速くなる ○ ただし、リファクタリングをする前にまずはテストを準備すること ● リファクタリングはタスクを切って行う ○ 機能開発をどう行うかはエンジニアの責任範囲 ○ それで開発が早くなるなら積極的にタスクを切る

Slide 49

Slide 49 text

| © 2024 Levtech Co., Ltd. 49 最後に(参考) リファクタリングいつやるの? ● 「リファクタリングの時間」を確保する技術@ログラステックブログ ● リファクタリング 既存のコードを安全に改善する@オーム社

Slide 50

Slide 50 text

最後に伝えたいこともう一度

Slide 51

Slide 51 text

リファクタリング、いつやるの?

Slide 52

Slide 52 text

一番お伝えしたいこと リファクタリングを止めるな 機能改修を止めるな 今でしょ

Slide 53

Slide 53 text

No content