Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
イージーからシンプルへ 〜プロダクトの成長に合わせたアーキテクチャの変更〜
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ham
February 22, 2023
Technology
4.9k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
イージーからシンプルへ 〜プロダクトの成長に合わせたアーキテクチャの変更〜
ham
February 22, 2023
More Decks by ham
See All by ham
プロダクト開発から業務改善コンサルまで。事業全体へ「染み出す」ことで広がるエンジニアの可能性
ham0215
0
150
AI時代に「チーム開発」を見直す ~個人アサインへのシフトと、AI駆動開発の実践例~
ham0215
0
48
機能開発を止めないために!運用と開発のバランスを可視化するために使っている指標をご紹介
ham0215
0
56
未来のAI駆動開発をイメージしながらAI開発基盤を整備する
ham0215
1
70
AIと過ごす1日〜全業務フローにAIを組み込む実践ガイド〜
ham0215
0
150
生成AIによる生産性向上〜テック企業やファインディの活用事例〜
ham0215
1
130
生成AI導入の効果を最大化する データ活用戦略
ham0215
0
570
データ駆動経営の道しるべ:プロダクト開発指標の戦略的活用法
ham0215
2
530
開発組織における意思決定の実例〜開発優先度・組織構成・ツール導入〜
ham0215
0
130
Other Decks in Technology
See All in Technology
AI Coding Agent時代のcdk-nagガードレール 〜組織ルールを強制CIで守り抜く設計の挑戦〜
mhrtech
3
510
AICoEでAIネイティブ組織への進化
yukiogawa
0
220
プロダクト開発組織の現在地(Ver.2026/07) / product-organization
kaonavi
0
400
”AIを使う” から ”AIに任せる” へ ─ 開発プロセスを再設計してAIを組織標準にするまで
cyberagentdevelopers
PRO
1
140
Alphaモジュール使っていいのかい!?いけないのかい!?どっちなんだいっ!?
watany
1
320
AIコード生成×サプライチェーン攻撃 — PHPが直面する“二重の信頼問題
shinyasaita
0
460
ダッシュボード"開発"について 〜使われるダッシュボードのつくりかた〜
kimichan
0
200
壊して学ぶAWS CDK: そのcdk deployで消えるもの、残るもの
k_adachi_01
1
480
テックカンファレンス三大ステークホルダーの文化人類学 ─ 違いを認め合う関係性作り
bash0c7
1
240
現場との対話から始める “作る前に問い直す”業務改善
mochico50
1
230
20260720_クラウド女子会×PyLadiesTokyoコラボ Amazon Bedrock ハンズオン用資料
yuuka51
1
110
AIツールを導入しても生産性はあがらない? カオナビが直面した 3つの壁と乗り越え方。/ Overcoming 3 Barriers to AI-Driven Productivity at kaonavi
kaonavi
0
190
Featured
See All Featured
The Mindset for Success: Future Career Progression
greggifford
PRO
0
430
The Limits of Empathy - UXLibs8
cassininazir
1
530
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
45k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
Technical Leadership for Architectural Decision Making
baasie
3
440
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
310
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
390
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
180
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
440
Transcript
イージーからシンプルへ 〜プロダクトの成長に合わせたアーキテクチャの変更〜 SaaSにおけるフロントエンドの技術戦略 | SaaS.tech #6 2023/02/22 ham
自己紹介 【略歴】 新卒でSIerとして就職 その後、Web系企業やスタートアップを経てファインディに参画 ファインディではFindy Team+のフロント&バックエンド開発を担当 React+Rails+GraphQL+AWSを使って開発しています 浜田 直人 (ham)
ファインディ株式会社 @hamchance0215
Findy Team+とは? https://findy-team.io GitHubやGitLab、Jiraなどエ ンジニア向けツールを解析す ることで、エンジニアリング組 織の生産性を可視化する サービスです。
プロダクトの歴史 2021/10 正式にローンチ 2022/10 Team+へ進化 生産性の可視化・向上に加え、エンジニ ア組織の「開発者体験」「改善文化」「採 用」を一貫してサポート 2020年 α版リリース
プロダクトの歴史 2021/10 正式にローンチ 2022/10 Team+へ進化 生産性の可視化・向上に加え、エンジニ ア組織の「開発者体験」「改善文化」「採 用」を一貫してサポート 2020年 α版リリース
プロダクトの成長と共にエンジニアが増加 チーム開発の効率を上げるためアーキテクチャを変更中
ローンチ当時の状況 2021/10 正式にローンチ • 不足している機能を新規開発し、顧客 価値を高めることに注力 ◦ 少人数でガンガン新規開発!
ローンチ当時の状況 2021/10 正式にローンチ • 不足している機能を新規開発し、顧客 価値を高めることに注力 ◦ 少人数でガンガン新規開発! • 簡単に使えることを重視
イージーなアーキテクチャ
現在の状況 2022/10 Team+へ進化 生産性の可視化・向上に加え、エンジニ ア組織の「開発者体験」「改善文化」「採 用」を一貫してサポート • 新規開発に加えて、既存機能をブラッ シュアップ ◦
既存機能を触る機会が増える • エンジニア増加。効率よくチーム開発 できることが重要 ◦ コードリーディングしやすく、誰で も触れるコードが良い
現在の状況 2022/10 Team+へ進化 生産性の可視化・向上に加え、エンジニ ア組織の「開発者体験」「改善文化」「採 用」を一貫してサポート • 新規開発に加えて、既存機能をブラッ シュアップ ◦
既存機能を触る機会が増える • エンジニア増加。効率よくチーム開発 できることが重要 ◦ コードリーディングしやすく、誰で も触れるコードが良い 簡単に理解できることを重視 シンプルなアーキテクチャ
イージーからシンプルへ
イージーからシンプルへ
イージーなアーキテクチャ ・Filterに指定した条件のデータを表示す る画面 ・画面ごとにFilterの種類や数、表示する データが違う
イージーなアーキテクチャ const [filters, setFilters] = useState(); return ( <Layout> <h1>Hoge画面</h1>
<Filters setFilters={setFilters} /> <div> Hogeなデータが表示されます </div> <DataTable type={hoge} filters={filters} /> </Layout> ); 各画面にFilterがあるのでまとめて <Filters />を作ろう
イージーなアーキテクチャ const [filters, setFilters] = useState(); return ( <Layout> <h1>Hoge画面</h1>
<Filters setFilters={setFilters} /> <div> Hogeなデータが表示されます </div> <DataTable type={hoge} filters={filters} /> </Layout> ); データ表示は<DataTable />を作ろう データ取得処理も内部に隠蔽すれば楽だな
イージーなアーキテクチャ const [filters, setFilters] = useState(); return ( <Layout> <h1>Fuge画面</h1>
<Filters setFilters={setFilters} disabledFilter3={true} /> <div> Fugeなデータが表示されます </div> <DataTable type={fuga} filters={filters} /> </Layout> );
イージーなアーキテクチャ const [filters, setFilters] = useState(); return ( <Layout> <h1>Fuge画面</h1>
<Filters setFilters={setFilters} disabledFilter3={true} /> <div> Fugeなデータが表示されます </div> <DataTable type={fuga} filters={filters} /> </Layout> ); 簡単に使えることを重視 共通コンポーネントをぽんぽん置いていく だけで類似画面が量産できる!
イージーなアーキテクチャ const Filters = ({ setFilters, disableFilter1, disableFilter2, disableFilter3, …
}) => { // いろいろなしょり … }); [props] 利用元の仕様を吸収する ため増加していく [処理] データ取得やレイアウトなど様々な責務を持ってい たり、利用元の様々なパターンに対応するため処理 が複雑に 一方、共通コンポーネント内は肥大化&複雑化していく... [テスト] コンポーネント内に外部 APIやGlobal Store への接続が混在しているため、テストが大変 大量のMockが必要となる
• 簡単に使えることを重視 ◦ 共通コンポーネントをぽんぽん置いていくだけで類似 画面が量産できる! ◦ 共通コンポーネント内が複雑になり、一定水準を超え ると簡単に使うことも難しくなる • 責務が複数あり、処理が複雑になりやすい
◦ キャッチアップが難しく、属人化が進む ◦ テストが書きづらい イージーなアーキテクチャ
イージーからシンプルへ
シンプルなアーキテクチャ // 外部APIやGlobal Stateへの接続を集約 const {data, options1, …, } =
useFacade(); return ( <Layout> <h1>Hoge画面</h1> // Filterは1つずつ配置 // 内部でデータ取得などはせずoptionsやeventは外から渡す <Filter options={options1} onChange={onChange1}/> <Filter options={options2} onChange={onChange2}/> <Filter options={options3} onChange={onChange3}/> <div> Hogeなデータが表示されます </div> // 取得したデータを渡し、DataTableは表示に専念 <DataTable data={data} /> </Layout> );
シンプルなアーキテクチャ // 外部APIやGlobal Stateへの接続を集約 const {data, options1, …, } =
useFacade(); return ( <Layout> <h1>Hoge画面</h1> // Filterは1つずつ配置 // 内部でデータ取得はせずoptionsやeventはpropsで渡す <Filter options={options1} onChange={onChange1}/> <Filter options={options2} onChange={onChange2}/> <Filter options={options3} onChange={onChange3}/> <div> Hogeなデータが表示されます </div> // 取得したデータを渡し、DataTableは表示に専念 <DataTable data={data} /> </Layout> ); 関数の責務を明確にする 名前を見るだけでやっていることが想像できる のでコードリーディングが簡単 新しいメンバーがキャッチアップしやすい データ取得などを呼び出し元で行うため、イー ジーと比べて一手間必要になる (やることは明確)
シンプルなアーキテクチャ // 外部APIやGlobal Stateへの接続を集約 const {data, options1, …, } =
useFacade(); return ( <Layout> <h1>Hoge画面</h1> // Filterは1つずつ配置 // 内部でデータ取得はせずoptionsやeventは外から渡す <Filter options={options1} onChange={onChange1}/> <Filter options={options2} onChange={onChange2}/> <Filter options={options3} onChange={onChange3}/> <div> Hogeなデータが表示されます </div> // 取得したデータを渡し、DataTableは表示に専念 <DataTable data={data} /> </Layout> ); 過度な共通化は行わない イージーよりコード量が増えるが、コン ポーネントが疎結合になり影響範囲が局 所化できて変更に強い
シンプルなアーキテクチャ const Filter = ({ selectedValue, options, onChange }) =>
{ const {state, handleHoge} = useFilter(); return ( <Select options={options} value={selectedValue} onChange={onChange} onHoge={handleHoge} /> ); }); [props] 表示に必要なデータは内部で取得せ ず、propsで受け取る componentは表示に専念 component内部でstateや callbackなどが必要な場合、専 用の関数で管理 共通コンポーネント内も責務を分離してシンプルに! [テスト] componentは外部接続などを行わないた め、テストやStrorybookが実装しやすい モック地獄からの解放
• 簡単に使えることより、簡単に理解できる(=シンプルな 実装)ことを重視 • 責務を明確にすることで可読性UP ◦ テストが書きやすい • 過度な共通化をしない ◦
コード量は増えるが変更に強い • キャッチアップしやすく、新しいメンバーに優しい ◦ チーム開発に向いている シンプルなアーキテクチャ
途中経過
アーキテクチャ変更の途中経過 12月から開始して現時点で半分ほど完了 一人当たりのプルリク作成数が増加中!! 一人当たりの プルリク作成数 約1.5倍に!! ※Findyではプルリク作成数 を開発生産性の1つの指標と して見ることが多い
イージーからシンプルへ 〜プロダクトの成長に合わせたアーキテクチャの変更〜 ご清聴ありがとうございました