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
1.9k
循環的複雑度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
350
_何となく_世界からオファーが来る_エンジニアのなり方LT.pdf
shuuumai
1
440
シェアリングサービスのトランザクションを支えるGo
shuuumai
0
200
シューマイ_Tech_Lead_Engineerから最新技術を学べ_Rails編_登壇資料.pdf
shuuumai
0
430
シューマツワーカー サービス資料
shuuumai
0
360
POL流レバレッジの効いたエンジニア組織を作る
shuuumai
1
390
REACT_NATIVE_EXPOで行うアプリの簡単最速運用_渡邊様_登壇資料_.pdf
shuuumai
0
270
Other Decks in Programming
See All in Programming
テストケースの名前はどうつけるべきか?
orgachem
PRO
0
140
モバイルアプリにおける自動テストの導入戦略
ostk0069
0
110
今年一番支援させていただいたのは認証系サービスでした
satoshi256kbyte
1
260
今年のアップデートで振り返るCDKセキュリティのシフトレフト/2024-cdk-security-shift-left
tomoki10
0
210
PHPで作るWebSocketサーバー ~リアクティブなアプリケーションを知るために~ / WebSocket Server in PHP - To know reactive applications
seike460
PRO
2
470
毎日13時間もかかるバッチ処理をたった3日で60%短縮するためにやったこと
sho_ssk_
1
120
create_tableをしただけなのに〜囚われのuuid編〜
daisukeshinoku
0
260
MCP with Cloudflare Workers
yusukebe
2
220
Go の GC の不得意な部分を克服したい
taiyow
3
790
The Efficiency Paradox and How to Save Yourself and the World
hollycummins
1
450
KubeCon + CloudNativeCon NA 2024 Overviewat Kubernetes Meetup Tokyo #68 / amsy810_k8sjp68
masayaaoyama
0
250
バグを見つけた?それAppleに直してもらおう!
uetyo
0
180
Featured
See All Featured
Music & Morning Musume
bryan
46
6.2k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
Imperfection Machines: The Place of Print at Facebook
scottboms
266
13k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
Navigating Team Friction
lara
183
15k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
A Modern Web Designer's Workflow
chriscoyier
693
190k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
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 を選んでおくと間違いはない