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
循環的複雑度80超えの現行システムに Laravel × オニオンアーキテクチャ で立ち向かっ...
Search
最新技術のエンジニア勉強会!シューマイ! ~Tech Lead Engineer~
July 08, 2020
Programming
1
2k
循環的複雑度80超えの現行システムに Laravel × オニオンアーキテクチャ で立ち向かった話(栗原 史明 氏*株式会社うるる)
最新技術のエンジニア勉強会!シューマイ! ~Tech Lead Engineer~
July 08, 2020
Tweet
Share
More Decks by 最新技術のエンジニア勉強会!シューマイ! ~Tech Lead Engineer~
See All by 最新技術のエンジニア勉強会!シューマイ! ~Tech Lead Engineer~
Rails_and_spice
shuuumai
2
370
_何となく_世界からオファーが来る_エンジニアのなり方LT.pdf
shuuumai
1
450
シェアリングサービスのトランザクションを支えるGo
shuuumai
0
210
シューマイ_Tech_Lead_Engineerから最新技術を学べ_Rails編_登壇資料.pdf
shuuumai
0
440
シューマツワーカー サービス資料
shuuumai
0
390
POL流レバレッジの効いたエンジニア組織を作る
shuuumai
1
410
REACT_NATIVE_EXPOで行うアプリの簡単最速運用_渡邊様_登壇資料_.pdf
shuuumai
0
280
Other Decks in Programming
See All in Programming
新宿駅構内を三人称視点で探索してみる
satoshi7190
2
120
お前もAI鬼にならないか?👹Bolt & Cursor & Supabase & Vercelで人間をやめるぞ、ジョジョー!👺
taishiyade
7
4.2k
Jakarta EE meets AI
ivargrimstad
0
350
Boost Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
820
CI改善もDatadogとともに
taumu
0
200
Flutter × Firebase Genkit で加速する生成 AI アプリ開発
coborinai
0
170
Jakarta EE meets AI
ivargrimstad
0
400
PRレビューのお供にDanger
stoticdev
1
230
クリーンアーキテクチャから見る依存の向きの大切さ
shimabox
5
1k
Rails 1.0 のコードで学ぶ find_by* と method_missing の仕組み / Learn how find_by_* and method_missing work in Rails 1.0 code
maimux2x
1
220
一休.com のログイン体験を支える技術 〜Web Components x Vue.js 活用事例と最適化について〜
atsumim
0
980
Datadog Workflow Automation で圧倒的価値提供
showwin
1
160
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.4k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
133
33k
Code Reviewing Like a Champion
maltzj
521
39k
Documentation Writing (for coders)
carmenintech
67
4.6k
Visualization
eitanlees
146
15k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Testing 201, or: Great Expectations
jmmastey
42
7.2k
The Cult of Friendly URLs
andyhume
78
6.2k
How STYLIGHT went responsive
nonsquared
98
5.4k
For a Future-Friendly Web
brad_frost
176
9.6k
Building Your Own Lightsaber
phodgson
104
6.2k
Transcript
循環的複雑度 30 超えのシステムに Laravel × Onion Architecture で 立ち向かっ(た)ている話 2020/07/08
【シューマイ】Tech Lead Engineerから最新技術を学べ!Laravel編 株式会社うるる NJSS事業部 プロダクト開発課 栗原 史明
Agenda • はじめに • 自己紹介 • Onion Architecture って何? •
Laravel x Onion Architecture • 具体例 • 実際やってみてどうだったか • まとめ
はじめに
• 今回お話すること ◦ オニオンアーキテクチャの重要となる部分の解説 ◦ Laravelで実装する場合の簡単な具体例 ◦ 実際に導入してみて改善・実感できたことと課題のお話 • 話さないこと
◦ Laravelの基本的機能の解説 ◦ オニオンアーキテクチャを使った詳細な実装のお話 ◦ オニオンアーキテクチャの詳細な解説 ◦ DDD(ドメイン駆動開発)の詳細なお話 はじめに
自己紹介 誰ですかあなた
自己紹介 • 栗原 史明 • 株式会社うるる ◦ NJSS事業部 プロダクト開発課 •
Laravel / Lumen • Docker / AWS / terraform / CDK • 認定スクラムマスター • あつ森で永遠と川を掘ってる
株式会社うるる では一緒に働く仲間を募集中! • 「人のチカラで世界を便利に」 ◦ 人のチカラ(クラウドワーカー)を活用したサービスを展開する会社です • サーバーサイドエンジニア募集中!(2020/07/07現在) ◦ 興味がありましたら是非お声掛けください!
◦ うるるの歩みと未来 ◦ うるるのエンジニア紹介
Onion Architecture って何? フレームワークではない、設計のお話
Onion Architecture 引用: https://buildersbox.corp-sansan.com/entry/2019/07/10/110000
このあたりの本も参考に
Q. オニオンアーキテクチャが 実現したいことってなんですか?
A. 「重要なもの」を「些細なもの」に 依存させない 引用: https://www.slideshare.net/ShoheiOkada/laravel-shuumai?next_slideshow=1
岡田正平さんのスライドが とても綺麗にまとまってます 参考: https://www.slideshare.net/ShoheiOkada/laravel-shuumai?next_slideshow=1
Onion Architecture が実現したいこと • 重要なもの ◦ ビジネスロジック ▪ システム/プロダクトが目的とする処理を行うところ ▪
例:売上計算のルール、日付の依存関係のルール など ◦ • 些細なもの ◦ フレームワーク、DB、テスト、インフラ、UI、ORM etc ◦ ※あくまでも「クリーンアーキテクチャ」の考え方で判断した場合
Onion Architecture が実現したいこと • 重要なもの ◦ ビジネスロジック ▪ システム/プロダクトが目的とする処理を行うところ ▪
例:売上計算のルール、日付の依存関係のルール など ◦ 変更が発生しにくい • 些細なもの ◦ フレームワーク、DB、テスト、インフラ、UI、ORM etc ◦ 簡単に変更できるもの/すべきもの ※あくまでも「クリーンアーキテクチャ」の考え方で判断した場合
Laravel x Onion Architecture では、なぜ我々は [ Laravel ] を選択したのか
プロジェクト発足時に抱えてた思い (エンジニア目線) • メンテナンス性を上げたい ◦ Fat Controller / Fat Model
で読みづらい ▪ メンテの度に4000行超えClass読むのしんどい ◦ テストが存在しない、というか循環的複雑度30超え当たり前 のメソッドにテスト書くなんて無理 • フレームワークであまり悩みたくない ◦ フレームワークは開発を補佐するものであり、設計を考える ことに時間を使いたかった
なぜ、我々はLaravelを選択したのか • フレームワークの自由度が高く Onion Architecture の ディレクトリ構成を表現しやすい • Onion Architecture
に必須なDIをデフォルトでサポート • トラブルシューティングがしやすい
Laravel x Onion Architecture • フレームワークの自由度が高く Onion Architecture の ディレクトリ構成を表現しやすい
◦ 基本的なMVCモデルではないディレクトリの切り方でも、 Laravelなら対応できる ▪ 自分たちの特性に合わせたディレクトリ構成を組みやすい ◦ やっぱり何かと便利なEloquent ◦ 足りない機能をComposerで補う動きもやりやすい
Laravel x Onion Architecture • Onion Architecture に必須なDIをデフォルトでサポート ◦ Interface
から実体Classを呼ぶための機能 ◦ Providerに対して app->bind() で設定することができる
Laravel x Onion Architecture • トラブルシューティングがしやすい ◦ 公式DocやQiitaなど日本語のドキュメントが豊富 ◦ Laravel起因のエラーは大体誰かが経験している
▪ ggrな状況になっても割とどうにかなる ◦ 挑戦的なアーキテクチャの導入は最初は迷いやすいので、フ レームワーク起因のトラブルが対処しやすいのは迷うポイン トを減らす観点で大きなメリット
For Example 簡単な例からイメージを
具体例 • こういう要件があったとする ◦ ユーザ情報を保存するAPIを作りたい ◦ 保存する内容は 名前 / ニックネーム
/ メアド ◦ ユーザ識別詞としてメアドをsha256でハッシュ化する ※「こんな要件本当に存在するのか?」 という質問については一例なので気にしたら負けです。
具体例
具体例 データベースを変更したら死ぬ ぴえん
要件の実現は出来ている 【が】 「重要なもの」が 「些細なもの」の変更で 処理が壊れてしまう
Laravel でどうやって実現するか • ビジネスロジックの実装 ◦ app配下にビジネスロジックを配置するディレクトリを作成 し、そこに集約する • 永続化層を抽象化 ◦
特定のインフラに依存するものは抽象化する ◦ 抽象化したクラスをProviderで紐付ける
ビジネスロジックの実装 • アプリ固有の機能/ルールをClass化しDomain層に表現 ◦ Laravelではディレクトリを自由に切りやすい 「メアドでsha256する」という ビジネスロジックが Domain層に表現される
永続化層の抽象化 • Interfaceを定義し、実体Classを実装 ◦ EloquentやMySQLなどの処理はここに記述する
永続化層の抽象化 • Interfaceと実体Classを紐付ける LaravelではDIを標準サポート
永続化層の抽象化 • Interfaceで型宣言を しているが、実際の処 理では実体クラスが渡 される
A. 「重要なもの」が「些細なもの」に 依存しない形にすることができた! ビジネスロジック DB / フレームワーク / ORM 等
実際やってみてどうだったか Laravel を通じて変化に強いコードへ
プロジェクト発足時に抱えてた思い (エンジニア目線) • メンテナンス性を上げたい ◦ Fat Controller / Fat Model
で読みづらい ▪ メンテの度に4000行超えClass読むのしんどい ◦ テストが存在しない、というか循環的複雑度30超え当たり前 のメソッドにテスト書くなんて無理 • フレームワークであまり悩みたくない ◦ フレームワークは開発を補佐するものであり、設計を考える ことに時間を使いたかった
改善・実感できたこと • 可読性向上! ◦ まだ途中ではありますが、現時点でClass循環的複雑度の平均 値は 5 まで下がりました ◦ データベースの構造に依存していたビジネスロジックを分割
することができた ◦ これにより関心ごとがClassごとに表現され、可読性が向上
改善・実感できたこと • テストが書けるようになりバグ抑制に繋がった ◦ 責務を考えてクラスを分割しているのでその責務に特化した テストを書くことができるようになった ◦ DIが使えるためFeatureTestの際にMockを作ってException ケースを検証することも容易 ◦
機能改修/拡張をする際も実装済テストがあることでデグレ検 知ができる安心感
改善・実感できたこと • トラブルシューティングがしやすい ◦ 当初狙っていた「ドキュメントの充実」に起因したトラブル シューティングのしやすさは享受出来た ◦ オニオンアーキテクチャの設計に悩んでも、Laravelの使い方 に悩むことは少なかった
プロジェクト発足時に抱えてた思い (エンジニア目線) • メンテナンス性を上げたい ◦ Fat Controller / Fat Model
で読みづらい ▪ メンテの度に4000行超えClass読むのしんどい ◦ テストが存在しない、というか循環的複雑度30超え当たり前 のメソッドにテスト書くなんて無理 • フレームワークであまり悩みたくない ◦ フレームワークは開発を補佐するものであり、設計を考える ことに時間を使いたかった Onion Architecture の導入で改善!! Laravel の導入で実現!!
• とにかく設計に悩んだ。悩んでる。(※現在進行形) ◦ 慣れてないうちはどこの層に書けば良いのか悩んだ ◦ 慣れてくると今度はどこまで責務分割させるか悩んだ、今も 悩んでる ▪ 完璧に拘り過ぎるとClassの分割が多すぎてしんどい ▪
単純な実装の場合は却って複雑さを招く場合も ▪ 私のチームでもインフラ依存の完全な分割はやりきれてないですし、敢えて割り 切っている部分もあります とはいえ課題もあります
• Fat Repository予備軍はある ◦ データの依存関係が複雑なRepositoryの実装でmethod数が多 くなり、600行超えのものも ◦ 今のところ、メンテナンスにはさほど影響を与えていないの で放置してるが悪化する前に責務を上手く切り分けて薄くし たい
とはいえ課題もあります
まとめ Laravel を通じて変化に強いコードへ
Q. オニオンアーキテクチャが 実現したいことってなんですか?
A. 「重要なもの」を「些細なもの」に 依存させない 引用: https://www.slideshare.net/ShoheiOkada/laravel-shuumai?next_slideshow=1
Onion Architecture が実現したいこと • 重要なもの ◦ ビジネスロジック ▪ システム/プロダクトが目的とする処理を行うところ ▪
例:売上計算のルール、日付の依存関係のルール など ◦ 変更が発生しにくい • 些細なもの ◦ フレームワーク、DB、テスト、インフラ、UI、ORM etc ◦ 簡単に変更できるもの/すべきもの ※あくまでも「クリーンアーキテクチャ」の考え方で判断した場合
なぜ、我々はLaravelを選択したのか • フレームワークの自由度が高く Onion Architecture の ディレクトリ構成を表現しやすい • Onion Architecture
に必須なDIをデフォルトでサポート • トラブルシューティングがしやすい
Laravel でどうやって実現するか • ビジネスロジックの実装 ◦ app配下にビジネスロジックを配置するディレクトリを作成 し、そこに集約する • 永続化層を抽象化 ◦
特定のインフラに依存するものは抽象化する ◦ 抽象化したクラスをProviderで紐付ける
プロジェクト発足時に抱えてた思い (エンジニア目線) • メンテナンス性を上げたい ◦ Fat Controller / Fat Model
で読みづらい ▪ メンテの度に4000行超えClass読むのしんどい ◦ テストが存在しない、というか循環的複雑度30超え当たり前 のメソッドにテスト書くなんて無理 • フレームワークであまり悩みたくない ◦ フレームワークは開発を補佐するものであり、設計を考える ことに時間を使いたかった Onion Architecture の導入で改善!! Laravel の導入で実現!!
Q. オニオンアーキテクチャって 本当に効果あるの?
A. ビジネスロジックが複雑な プロダクトほど刺さると思います 逆にそんなに複雑じゃないよ、 という方が導入するとクラス管理が多くなるので しんどさの方が勝ってしまうかも
補足 • PHP7.4 が使えるなら PHP7.4 以上を推奨 ◦ プロパティ変数に型定義ができるので、型推論によりClassで 表現できる内容がより強化される •
本日会話した内容は Lumen でも(ほぼ)そのまま実現可能 ◦ 「Laravel側はAPIのみ」等の条件が揃えば Lumen でも実現可 能。速度要件があるなら一考の余地アリ ◦ ただし、Laravel 拡張が使えないパターンがあるので、不安で あれば Laravel を選んでおくと間違いはない