Slide 1

Slide 1 text

1 / 70 フロントエンド技術の波を乗り越える! Vue2からReactへの移行とアーキテクチャ設計による堅牢化 2024.7.30 クラスメソッド株式会社 産業支援グループ リテールアプリ共創部 中野ヨシユキ

Slide 2

Slide 2 text

2 / 70 中野ヨシユキ (@engin_yo) 所属: クラスメソッド 産業支援グループ リテールアプリ共創部 やってること: LINE ミニアプリの機能開発、保守、運用 ロール: ソフトウェアエンジニア 趣味: ランニング、自作キーボード 自己紹介

Slide 3

Slide 3 text

3 / 70 このセッションでは、私の経験と学びを共有します 一方で、本セッションの内容が、すべてのプロジェクトやチームに適用できるわけではないことを ご理解ください また、特定の技術や手法を批判するわけではないこと、ご理解ください 本日のセッションから1つでも何かを持ち帰っていただき、ソフトウェア開発や保守に活かしてい ただけるとうれしいです はじめに

Slide 4

Slide 4 text

4 / 70 レガシーなソフトウェアの保守がつらいと思っている方 初期開発の担当者がいない中、ソフトウェアのエンハンスを迫られている方 ソフトウェアアーキテクチャ理論の実践に興味がある方 本セッションのターゲット

Slide 5

Slide 5 text

5 / 70 Vue2からReactへリライトを意思決定した理由 リライトヘ当たって直面した課題 課題を解決するための取り組み フロントエンドクリーンアーキテクチャ導入解説 リライト後の変化 学んだ教訓 目次

Slide 6

Slide 6 text

6 / 70 Vue2からReactへリライトを意思決定した理由

Slide 7

Slide 7 text

7 / 70 Vue2は2023年12月末に EOL (End of Life) を迎えていた 参考: https://v2.vuejs.org/eol/ 正規ルートだと「Vue2からVue3」 、現トレンドだと「Vue2からReact」にするか、世間では大きく 2つのルートに分かれていた Vue 2 の最新リリースである 2.7.16 は、Vue 2 の最終リリース。2.7 機能の最終的な修正が含まれ ており、さらに、Vue 3 との型の整合性がある 理由1: Vue2のEOL

Slide 8

Slide 8 text

8 / 70 Options APIを利用している場合、Composition APIへの置き換えが必要 Vue2だと、各コンポーネントのthisに状態を変更するロジックが依存するため関心事の単位で関数 をまとめることが難しく、Options APIを利用するコード周辺に分散しがちで「状態を持つ関数」 の再利用しにくい Vue2に関連付属するライブラリの置き換えが必要 例: Vuetify VueCLI 理由2: Vue2からVue3の移行のコスト

Slide 9

Slide 9 text

9 / 70 Vue2の場合(コンポーネントがthis依存) 理由2: Vue2からVue3の移行のコスト import Vue from "vue/dist/vue.esm"; new Vue({ el: "#app", data: { message: "This is Vue 2", count: 0, }, methods: { increment() { this.count++; }, decrement() { this.count--; }, }, template: `

Count: {{ count }}

Increment Decrement

Slide 10

Slide 10 text

10 / 70 Vue3の場合(Composition APIによる関数再利用) 理由2: Vue2からVue3の移行のコスト import { createApp, ref } from "vue"; import { useCounter } from "./useCounter"; const App = { setup() { const message = ref("This is Vue 3"); const { count, increment, decrement } = useCounter(); return { message, count, increment, decrement, }; }, template: `

Count: {{ count }}

Increment Decrement
`, };

Slide 11

Slide 11 text

11 / 70 import { ref } from "vue"; export const useCounter = () => { const count = ref(0); const increment = () => { count.value++; }; const decrement = () => { count.value--; }; return { count, increment, decrement, }; };

Slide 12

Slide 12 text

12 / 70 Reactは現行のトレンドだとVueよりも主流になっている 今後、追加の機能開発をすすめていく場合は、私たちのチームでVueよりも開発工数が少なめで対 応可能であると判断 参考: State of JavaScript 2023 Front-end Frameworks 理由3: React主流による保守体制確保の容易性

Slide 13

Slide 13 text

13 / 70 私たちLINEミニアプリ運用保守チームは、技術スタックを可能な限りそろえる方針をとっており、 技術への認知負荷低減を目標にしている 目的としては、チームが顧客へ価値提供する速度を上げるため 理由4: チームの技術スタックをそろえることによる効用

Slide 14

Slide 14 text

14 / 70 システムエントロピーという概念 定義 組織全体で技術スタックが統一されていれば「エントロピーは低い」 バラバラな技術が採用されていれば「エントロピーは高い」 特徴 エントロピー低い状態 システムのエントロピーが低ければ低いほど、システム理解は簡単 改修のハードルが低く、トイル(手作業)の削減や自動化を推進しやすい エントロピー高い状態 エントロピーが高くなると、システム理解に時間がかかりやすい 自動化や改善のハードルや手間が高まる傾向にある 参考:Satoshi Tajima 「システムのエントロピーをコントロールすることの大切さ」より 理由4: チームの技術スタックをそろえることによる効用

Slide 15

Slide 15 text

15 / 70 標準スタック フロントエンド:React、TypeScript バックエンド:Node.js(Express) 、TypeScript インフラ:AWS, Google Cloud, AWS CDKやCDKTfなどのIaCサービス 実際に各プロダクト毎の技術スタックをそろえた実際の効果 新しくプロジェクトにはいったオンボーディングのキャッチアップ速度が早い 1つのプロダクトを理解すると、それ以外のプロダクトはそれまでのシステム構成の差異をもと にキャッチアップできる(メンタルモデル形成の後押し) 参考: 「プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ」 細かいライブラリやビジネスルールは異なるが、各プロダクトの良い部分・悪い部分が明確にわ かる 私たちのチームの例

Slide 16

Slide 16 text

16 / 70 当初のアプリ開発メンバーはプロジェクトから外れており、保守フェーズ後も何度か担当者が変更 ソフトウェアプロダクトにおいて担当者の交代は「あるある」 例 初期開発担当者 保守フェーズ後のエンハンス開発者 運用保守担当者 担当者が変わって継続してユーザーへ価値提供を促進できるよう、情報を理解しやすい形にとどめ ておくことが必要 理由5: メンバー変更によるナレッジ不足の補強

Slide 17

Slide 17 text

17 / 70 ただ、ビックリライトを進めるだけならソフトウェアエンジニア側からみたらにコードを書けるか らうれしい リライトはいい面だけでなくリスクも大きい リグレッションのリスク 見積もりに対する予算超過 ステークホルダーやユーザーにとってのメリットを考える必要もある リライトすることによるステークホルダーの見返りを考える 例 ビッグリライトする代わりに新機能を追加で入れる(LINEミニアプリに新機能追加) セキュリティ面が補強される最新のアーキテクチャにできる キャッシュ機構を導入しレスポンスが高速化し品質向上 理由6: 今後のビジネス価値への寄与に期待できた

Slide 18

Slide 18 text

18 / 70 ビックリライトを決断!!

Slide 19

Slide 19 text

19 / 70 リライトするにあたり直面した課題

Slide 20

Slide 20 text

20 / 70 開発から保守フェーズまでの間に、メイン担当者が複数回変更 プロダクトに対する深いコンテキストが失われていた 顧客との関係性 プロダクト本当に実現したいこと プロダクトの業務ルール プロダクトを構成する特殊な環境や外部リソースの制約 課題1: コンテキストの喪失

Slide 21

Slide 21 text

21 / 70 複数のツールにドキュメントが散らばっていたり、Wikiに大事な情報がのっていなかったり 各種ツール GitHub Wiki Backlog Slack etc… できる限りドメイン知識はソースコードをドメインモデルとして構築 ドメインモデルを読めばドメイン知識がわかるようにすることで実際に動いているコードがドキュ メントにもなる 課題2: ドキュメントの散在

Slide 22

Slide 22 text

22 / 70 DEVやSTG環境の差異があるが、利用手順が不明なため開発には入れない 外部に依存するAPIを呼び出す際の事前のIP許可が必要で結合テストが難しい PRD Frontend (CloudFront + S3) External API STG Frontend (CloudFront + S3) External API (IP 制限あり) DEV Frontend (CloudFront + S3) Mock API 課題3: 開発環境の不整備

Slide 23

Slide 23 text

23 / 70 テスト仕様書が存在しない テストコードも存在せず、機能の期待する結果の判断が難しかった 旧環境のアプリを触り倒して把握したり、Vue2のコードを読み込む必要があった 課題4: テストコードの欠如

Slide 24

Slide 24 text

24 / 70 課題を解決するための取り組み

Slide 25

Slide 25 text

25 / 70 コンテキストが喪失しているため、コードを書く前にまずはドメイン知識の理解を進めた 具体的にやったこと プロダクトを使った実際のユーザー体験(例:店舗にいってサービスを使ってみる) ドキュメントを一通りざっと読んでみる。別の開発者と不明点をディスカッションする 取り組み1: ドメイン知識を把握する時間をもつ

Slide 26

Slide 26 text

26 / 70 取り組み2: ドキュメント整備を並行して実施

Slide 27

Slide 27 text

27 / 70 開発初期から、開発環境と環境構築自動化にコストをかける GitHub Actionsを利用したCI/CD環境構築 ローカル環境整備(フロントエンドビルドツールのVite) 初期コストは後々になって恩恵として返ってくる 環境毎の差異や開発者毎に環境がことならないよう仕組み化しておくことで開発後もメンテナビリ ティ向上 取り組み3: 開発環境整備と自動化に時間を惜しまない

Slide 28

Slide 28 text

28 / 70 AWS(PRD) AWS(STG) AWS(DEV) mainブランチ(GitHub) featureブランチ(GitHub) Local PC AWS(PRD) AWS(STG) AWS(DEV) mainブランチ(GitHub) featureブランチ(GitHub) Local PC DEV・STG環境へデプロイ PRD環境へデプロイ プルリクエストを作成 git push テストコード実行 コードレビュー プルリクエストをマージ プルリクエストをmainにマージ GitHub Actions ワークフローがトリガー DEV環境にデプロイ(cdk deploy) GitHub Actions ワークフローがトリガー STG環境にデプロイ(cdk deploy) デプロイ完了通知 リリースノートを作成 リリースノートをpublish GitHub Actions ワークフローがトリガー PRD環境にデプロイ デプロイ完了通知

Slide 29

Slide 29 text

29 / 70 ビックリライトはリスクが大きい

Slide 30

Slide 30 text

30 / 70 もう2度とビックリライトというペインを 誰にも追従させたくない!

Slide 31

Slide 31 text

31 / 70 そうだ、そういえば

Slide 32

Slide 32 text

32 / 70 クリーンアーキテクチャがあった!

Slide 33

Slide 33 text

33 / 70 特定フレームワークやライブラリ依存の排除 クリーンアーキテクチャ(レイヤードアーキテクチャ)をベースに、コアなドメインロジック、ド メインモデルをライブラリやフレームワークからの依存から引き剥がす 置き換えの時に、フレームワークやライブラリに密結合した部分の大幅な書き換えをなくす 参考:Robert C.Martin「Clean Architecture 達人に学ぶソフトウェアの構造と設計」 取り組み4: クリーンアーキテクチャの採用

Slide 34

Slide 34 text

34 / 70 フロントエンドクリーンアーキテクチャ導入解説

Slide 35

Slide 35 text

35 / 70 クリーンアーキテクチャは、システムの関心事を分離するためにソフトウェアをレイヤーに分割す る設計手法 Robert C. Martin氏が提唱(公開ブログ:2012年8月、書籍:2017年) https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.htmlより引用 クリーンアーキテクチャとは?

Slide 36

Slide 36 text

36 / 70 1. フレームワークに依存しない 特定のフレームワークやライブラリに依存しない フレームワークやライブラリをツールとして使用でき、システムをその制約にべったり合わせる ことは不要 つまり、フレームワークは、目的を達成するための手段の1つとしてとらえることができる 2. テスタビリティ(テスト容易性)向上 ビジネスルールはUI、データベース、Webサーバーなどの外部要素なしでテスト可能 3. UIに依存しない UIは簡単に変更可能で、ビジネスルールに影響を与えません 例として、Web UI(GUI)をコマンドラインインターフェース(CLI)に置き換えることが可能 クリーンアーテクチャで設計されたシステムの特徴

Slide 37

Slide 37 text

37 / 70 4. 特定のデータベースに依存しない OracleやSQL ServerをMongo、BigTable、CouchDBなどのDB が変わってもアプリケーションの機能を維持できる。ビジネスルールはデータベースに依存しませ ん。 5. 外部API、外部システムに依存しない ビジネスルールは外部の世界について何も知る必要がない https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.htmlより クリーンアーテクチャで設計されたシステムの特徴

Slide 38

Slide 38 text

38 / 70 各層の依存方向は中心に一方向 同心円は、円の中心に近づくほど抽象度レベルが上がっていく。円の外側はシステムの仕組み (詳細)、内側は方針(抽象)である。 ソースコードの依存性は、内側(上位レベルの方針)だけに向かっていなければいけない 各層の境界を越えるデータ 境界を越えるデータはシンプルなデータ構造にする。データ転送オブジェクト(DTO)などを使 用する。データベースのレコードやカラムの構造など、外部のフォーマットを内側のレイヤーに 渡すことは避ける 各層の境界を越えるときは依存関係ルールに従う 制御の流れに逆らうソースコードの依存関係を作成し、 「依存関係のルール」に従わせる(依存 性逆転の法則) 基本ルール

Slide 39

Slide 39 text

39 / 70 Web フレームワークやデータベースなどのアーキテクチャの外部に位置するツールが古くなった場 合、それらの古くなった要素を最小限の手間で別のツールに置き換えることができる 例: Vue -> React React -> Next.js React -> Svelte DynamoDB -> MongoDB 仮にフレームワークやデータベースに結合しすぎたソフトウェアの場合、リライトや大規模なリフ ァクタリングを迫られる 私たちの場合は、今後プロダクトとして成長を維持できると考えたため、このルールに従うことを 決断 ルールに従うことで得られる恩恵

Slide 40

Slide 40 text

40 / 70 Webは詳細(=技術的な手段の1つ) フレームワークは詳細 APIは詳細 クリーンアーキテクチャの観点

Slide 41

Slide 41 text

41 / 70 方針 WebフレームワークであるReactやUIのデザイン部分は、層の一番外側に配置 「ドメインルールやドメインモデル」は内側のコアロジックとして配置 このように配置することで内側に配置した外側ほど変わりにくい処理を閉じ込めて外側から の依存を減らす 依存を減らすことでWebフレームワークのトレンドやEOL、破壊的変更により環境が変わっ ても内側のロジックを守りやすい 私たちのプロダクトで適用した方針

Slide 42

Slide 42 text

42 / 70 アルバムと写真を表示する簡易アプリ Reactベースでフロントエンドをクリーンアーキテクチャで設計 参考:https://github.com/drumnistnakano/react-clean-architecture-sample サンプルコード

Slide 43

Slide 43 text

43 / 70 サンプルコード - アルバム画面 -

Slide 44

Slide 44 text

44 / 70 サンプルコード - 写真画面 -

Slide 45

Slide 45 text

45 / 70 JSONPlaceholder フェイクデータをオンラインで返してくれるREST APIサーバー サンプルコードのテストやプロトタイプ構築に活用 参考: JSONPlaceholder - Free Fake REST API 利用したAPI fetch("https://jsonplaceholder.typicode.com/albums/1/photos") .then((response) => response.json()) .then((json) => console.log(json)); [ { "albumId": 1, "id": 1, "title": "accusamus beatae ad facilis cum similique qui sunt", "url": "https://via.placeholder.com/600/92c952", "thumbnailUrl": "https://via.placeholder.com/150/92c952" }, --- 中略 --- ]

Slide 46

Slide 46 text

46 / 70 ディレクトリ構造 . └── src ├── core // コアロジック │ ├── domain // ドメイン層 │ │ ├── entities // エンティティ定義 │ │ ├── repository // リポジトリのインターフェース定義 │ │ └── support // API Clientなどのサポート関数の定義 │ ├── infrastructure // インフラ層のインターフェース格納先 │ │ ├── api-client // API Clientの実装詳細 │ │ ├── logger // Loggerの実装詳細 │ │ └── repository // リポジトリの実装詳細 │ ├── usecase // アプリケーションユースケース層 │ └── util // Coreで利用可能なユーティリティ関数 ├── di-container // 依存注入周り │ ├── env-util.ts │ ├── register-container.ts │ └── service-id.ts └── framework // フレームワーク層 ├── cli // CLI │ ├── controllers // Usecase層への橋渡し │ └── main.ts // CLIのエントリポイント └── web // Web ├── presenters // Usecase層への橋渡し ├── EntryPoint.tsx // Webのエントリポイント ├── components // Reactのコンポーネント群

Slide 47

Slide 47 text

47 / 70 https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.htmlより引用 再掲

Slide 48

Slide 48 text

48 / 70 レイヤー間の関係図

Slide 49

Slide 49 text

49 / 70 層 説明 Domain層 ドメインロジックを定義する層。ビジネスルールやエンティティを含む Infrastructure層 外部システムとのやり取りを担当。APIクライアントやデータベースアクセスを含む UseCase層 ユースケース。ドメイン層とインフラ層をつなぐ Framework層 ユーザーインターフェースを担当。Reactコンポーネントを含む レイヤー毎の定義

Slide 50

Slide 50 text

50 / 70 その他、詳細

Slide 51

Slide 51 text

51 / 70 "dependencies": { "@vanilla-extract/css": "1.15.3", "inversify": "6.0.2", "react": "18.3.1", "react-dom": "18.3.1", "react-lazy-load-image-component": "1.6.2", "react-router-dom": "6.25.0", "swr": "2.2.5", "zod": "3.23.8" }, "devDependencies": { "@inquirer/prompts": "5.1.2", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", "@types/react-lazy-load-image-component": "^1.6.4", "@vanilla-extract/vite-plugin": "4.0.13", "@vitejs/plugin-react-swc": "3.7.0", "@vitest/coverage-v8": "2.0.3", "dotenv": "16.4.5", "typescript": "5.5.3", "vite": "5.3.4", "vite-tsconfig-paths": "4.3.2", "vitest": "2.0.3" }, 技術スタック

Slide 52

Slide 52 text

52 / 70 Framework層にAtomicDesignのコンポーネントを配置 コンポーネント毎にvanilla-extractでデザインファイルを読み込む運用 TSの型付けができること、CSS Modulesへの移行コストが低そう、デザイナーにいただいたデザイ ンを流用しやすい Framework層にAtomicDesignのコンポーネントを内包 // photo-album/src/framework/web/components/templates/AlbumList.css.ts import { style } from "@vanilla-extract/css"; export const albumList = style({ display: "flex", flexWrap: "wrap", gap: "1rem", justifyContent: "center", padding: "1rem", }); --- 以下省略 ---

Slide 53

Slide 53 text

53 / 70 UseCaseの戻り値をDTOに履き替えて、ドメイン層の情報がしみださないようにする DTO定義は、以下 DTOでFramework層にCoreの情報が染み出させない // photo-album/src/core/usecase/find-album-use-case-dto.ts import type { Album } from "@/core/domain/entities/album"; type AlbumInfo = { id: number; title: string; }; export class FindAlbumUseCaseResponseDto { readonly albums: AlbumInfo[]; constructor({ albums }: { albums: Album[] }) { this.albums = albums.map((album) => ({ id: album.id, title: album.title, })); } }

Slide 54

Slide 54 text

54 / 70 DTOでFramework層にCoreの情報が染み出させない // photo-album/src/core/usecase/find-album-use-case-impl.ts export const buildFindAlbumUseCase = ({ albumRepository, logger, }: { albumRepository: AlbumRepository; logger: Logger; }): FindAlbumUseCase => { return async () => { logger.debug({ message: "use-case: find-album-use-case-impl" }); const result = await albumRepository.findAll(); --- 中略 --- return { success: true, data: new FindAlbumUseCaseResponseDto({ albums: result.data }), }; }; };

Slide 55

Slide 55 text

55 / 70 Repository、UseCase、Domain層に対するユニットテストの実装が可能 自前で作ったダミーオブジェクトを使って、依存性注入させている テストコード導入 // photo-album/src/core/usecase/find-album-use-case-impl.small.test.ts describe("FindAlbumUseCase tests", () => { test("should return all albums on successful fetch", async () => { const findAlbumUseCase = buildFindAlbumUseCase({ albumRepository: new AlbumRepositoryDummy({ findAllReturnValue: { success: true, data: [ { userId: 1, id: 1, title: "Album 1" }, { userId: 2, id: 2, title: "Album 2" }, ], }, }), logger: new LoggerDummy(), }); const result = await findAlbumUseCase(); expect(result).toEqual({ success: true, data: { albums: [

Slide 56

Slide 56 text

56 / 70 リライト後の変化

Slide 57

Slide 57 text

57 / 70 SWRをいれたことによりAPIフェッチで初回は時間がかかるものの、キャッシュを利用できるよう になった SWRとTanstack Queryで実装比較したが、SWRの方がバンドルサイズが軽量なことやオプションが 少なくシンプルな実装になるためSWRを選定 SWRの導入効果 // photo-album/src/framework/web/components/templates/AlbumList.tsx export const AlbumList: React.FC = ({ onSelectAlbum }) => { const { container } = useContext(DIContainerContext); const { data: albums, error: albumsError, isLoading: isAlbumsLoading, } = useSWR({ container }, useFetchAlbums, { suspense: true }); if (isAlbumsLoading) return ; if (albumsError) throw new Error(`loading albums: ${albumsError.message}`); return ( --- 以下省略 ---

Slide 58

Slide 58 text

58 / 70 不十分だったドキュメントを整備したことや、テストコードを書いたことで機能開発や保守での修 正を自信を持てるようになった 保守性の向上 // photo-album/src/core/domain/entities/album.ts import { z } from "zod"; const AlbumSchema = z.object({ userId: z.number(), id: z.number(), title: z.string(), }); export type AlbumProps = z.infer; export class Album { // --- 中略 ---- /** * アルバムID * * @example 1 */ readonly id: number; // --- 中略 ---

Slide 59

Slide 59 text

59 / 70 コード量が増えたため、レビュー負荷が上がった 頻度高くペアプロ、コードレビューで負荷を軽減 アーキテクチャ学習のチーム育成という観点からは結果的に良かった レガシーコードの改善は一人よりも二人、二人よりもチーム全員でやる 参考:レガシーソフトウェア改善ガイドより https://www.shoeisha.co.jp/book/detail/9784798145143 コード量の増加

Slide 60

Slide 60 text

60 / 70 学んだ教訓

Slide 61

Slide 61 text

61 / 70 リライトするときはインクリメンタルにしよう 複数ページがあるなら1つのページだけ 複数機能あるなら、機能を分解して1つだけ API呼び出しから画面描画までのシーケンスを分解して一部から 期待した動きになるか、一進一退しながら実装を進める TDDで各層ごとにテストコードを実装する。一歩一歩、終わりに向けて確実感が増す 教訓1: リライトは一気にしない

Slide 62

Slide 62 text

62 / 70 自分で生み出したコードを何年かたって他の人がビックリライトを考案させないようにする そのために、コードを小さく保って使い捨てても書き換えが容易にしておく 最小限の部分だけ修正すれば維持できるというのが最高な状態 教訓2: ビックリライトをさせないようコードを

Slide 63

Slide 63 text

63 / 70 プロダクトのコンテキストは当初から抜けてしまうことがしばしば 開発後に保守を最低限できるドキュメントを整備しておく GitHubのIssueやPRを、Wikiにリンクさせてまとめておくだけでも良し ドキュメントは作成だけでなく、更新もしていこう。更新する人を賞賛しよう! 教訓3: 情報の残し方もソフトウェア開発の設計の1つ

Slide 64

Slide 64 text

64 / 70 それは砕けた定義でいうと、 「開発者のコードが呼び出すものがライブラリで、開発者のコードを呼び出すものがフレームワー ク」 というものだ。 — 中略 — フレームワークは開発者のコードを呼び出すので、コードはフレームワークと高度な結合を作る。 ライブラリは一般的に、より汎用的なコードのため、結合の度合いは低くなる — 中略 — フレームワークはアプリケーションの基礎部分であるため、チームは積極的に更新を行わなければ ならない。 ライブラリは一般的にフレームワークよりも弱い結合点を形成するため、更新についてチームはよ りカジュアルに行うことができる 進化的アーキテクチャ「6.5.8 ライブラリのアップデートとフレームワークのアップデート」 教訓4: フレームワークは積極的更新を計画しておく

Slide 65

Slide 65 text

65 / 70 ソフトウェアの改善は、常にユーザーや顧客のために行うことを忘れない 改善の目的は、ユーザー体験の向上やビジネス価値の最大化である 技術的な美しさや最新技術の導入だけを目的にしない しかし、最新技術にBetできる余白ももっておけるように、使い捨てできるようミニアムなソフトウ ェアを保っておく 教訓5: ソフトウェアの改善は「誰のために」を忘れずに

Slide 66

Slide 66 text

66 / 70 さいごに

Slide 67

Slide 67 text

67 / 70 フレームワークやライブラリをつかうと楽に早く開発できる フレームワークやライブラリのクラスやメソッドを使い込んで思いっきり結合してくれることを提 供側は望んでいるし、利用者も同様 しかし、フレームワーク依存しすぎると自分たちが意図しない方向(フロントエンドのトレンド、 EOL、破壊的変更など)で書き換えやリファクタリングが必要になってくる場合がある チームでライブラリやフレームワーク自体を統一する標準化をとるのもいいが、 ソフトウェアアーキテクチャを統一して解決する考え方もある まとめ

Slide 68

Slide 68 text

68 / 70 Vue.js 公式: Vue 3 移行ガイド React 公式: Reactリファレンス Chris Birchall 著: レガシーソフトウェア改善ガイド Robert C. Martin 著: Clean Architecture 達人に学ぶソフトウェアの構造と設計 Neal Ford, Rebecca Parsons, Patrick Kua 著: 進化的アーキテクチャ 絶え間ない変化を支える 参考資料

Slide 69

Slide 69 text

69 / 70

Slide 70

Slide 70 text

70 / 70