Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
イージーからシンプルへ 〜プロダクトの成長に合わせたアーキテクチャの変更〜
Search
ham
February 22, 2023
Technology
5k
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
その投資は、資本になっていますか?AI時代の開発投資を、ROIだけで判断しない「開発資本」という考え方
ham0215
0
49
プロダクト開発から業務改善コンサルまで。事業全体へ「染み出す」ことで広がるエンジニアの可能性
ham0215
0
210
AI時代に「チーム開発」を見直す ~個人アサインへのシフトと、AI駆動開発の実践例~
ham0215
0
66
機能開発を止めないために!運用と開発のバランスを可視化するために使っている指標をご紹介
ham0215
0
66
未来のAI駆動開発をイメージしながらAI開発基盤を整備する
ham0215
1
210
AIと過ごす1日〜全業務フローにAIを組み込む実践ガイド〜
ham0215
0
160
生成AIによる生産性向上〜テック企業やファインディの活用事例〜
ham0215
1
160
生成AI導入の効果を最大化する データ活用戦略
ham0215
0
660
データ駆動経営の道しるべ:プロダクト開発指標の戦略的活用法
ham0215
2
570
Other Decks in Technology
See All in Technology
Deployment の 先にある AI Agent 基盤 - kagent vNext、Agent Substrate、Hermes から読み解く Agent Runtime の現在地 / k8s-matsuri-2-ai-agent-platform-amsy810
masayaaoyama
4
680
10Xに技術的負債をもたらした「2つの境界の歪み」その構造と解消への営み
10xinc
0
2.1k
人間はどの意思決定を手放せるのか
kawasima
15
7.5k
あけおめLINE 傾向とその対策
nasa9084
0
180
サーバーレスをどこまで使う? WebRTC対戦ゲームで選んだVPSとの共存設計
kaidouji85
0
190
負債のメタファと2026年 / Debt Metaphor in Agentic Engineering Age 202609 Edition
twada
PRO
10
4.3k
AI coding 整合正規方法
philipz
0
370
株式会社シーエーシー エンジニア向け会社紹介資料
cac
0
57k
AIで社員の自主発信に広報目線を組み込む
_mossann_t
0
130
.NET WebAssemblyで実現するクライアントサイドAI推論:NuGetからViteまで、2つのエコシステムを繋ぐビルド戦略
yamachu
0
260
新機種発売前に見直そう!端末移行で再ログインが要るアプリ・要らないアプリは何が違うのか 〜シームレスに再開できる設計と実装〜
zozotech
PRO
0
220
2026_devsumi_ozono.pdf
o3
3
530
Featured
See All Featured
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
440
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
280
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Mobile First: as difficult as doing things right
swwweet
225
10k
Visualization
eitanlees
152
17k
Paper Plane
katiecoart
PRO
4
53k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Optimizing for Happiness
mojombo
378
71k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
380
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
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つの指標と して見ることが多い
イージーからシンプルへ 〜プロダクトの成長に合わせたアーキテクチャの変更〜 ご清聴ありがとうございました