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
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
140
AI時代に「チーム開発」を見直す ~個人アサインへのシフトと、AI駆動開発の実践例~
ham0215
0
45
機能開発を止めないために!運用と開発のバランスを可視化するために使っている指標をご紹介
ham0215
0
56
未来のAI駆動開発をイメージしながらAI開発基盤を整備する
ham0215
1
65
AIと過ごす1日〜全業務フローにAIを組み込む実践ガイド〜
ham0215
0
140
生成AIによる生産性向上〜テック企業やファインディの活用事例〜
ham0215
1
130
生成AI導入の効果を最大化する データ活用戦略
ham0215
0
570
データ駆動経営の道しるべ:プロダクト開発指標の戦略的活用法
ham0215
2
530
開発組織における意思決定の実例〜開発優先度・組織構成・ツール導入〜
ham0215
0
130
Other Decks in Technology
See All in Technology
型は壁、Rustでもバグを直すな、表現できなくせよ
nwiizo
12
1.8k
AWS Blocks を触ってみた/first-tach-aws-blocks
fossamagna
2
150
ループエンジニアリングでE2Eテストを実践
noriyukitakei
0
320
AI駆動開発におけるQAエンジニアの役割事例 〜AI駆動開発の現場から〜
kobayashiyorimitsu
0
400
SRE Lounge Hiroshimaへの招待
grimoh
0
420
ローカルLLMとLINE Botの組み合わせ その3 / LINE DC Generative AI Meetup #8
you
PRO
0
130
なぜ私たちのSREプラクティスはなかなか機能しないのか 〜システムより先に組織を見る〜 / Why our SRE practices aren't really working
vtryo
3
2.9k
Oracle Exadata Database Service on Cloud@Customer X11M (ExaDB-C@C) サービス概要
oracle4engineer
PRO
2
8.4k
記録をかんたんに、提案をパーソナルに ── AIであすけんが目指すもの
oprstchn
0
170
AI Agent SaaS を支える自社仮想化基盤への挑戦と実運用 / ai-agent-saas-virtualization
flatt_security
2
3.2k
Empower GenAI with Agile - あなたのアジャイルが生成AIのバフになる仕組み
hageyahhoo
1
140
Baseline対応のDOMの型定義を作った
uhyo
3
720
Featured
See All Featured
Building Applications with DynamoDB
mza
96
7.1k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
600
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
How STYLIGHT went responsive
nonsquared
100
6.2k
How to train your dragon (web standard)
notwaldorf
97
6.7k
Between Models and Reality
mayunak
4
360
Docker and Python
trallard
47
3.9k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
380
Designing for Performance
lara
611
70k
Statistics for Hackers
jakevdp
799
230k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
410
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
400
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つの指標と して見ることが多い
イージーからシンプルへ 〜プロダクトの成長に合わせたアーキテクチャの変更〜 ご清聴ありがとうございました