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
Laravelを始めて DDDを実践するまで
Search
Kazuki Ohashi
March 08, 2018
Technology
2k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Laravelを始めて DDDを実践するまで
Laravelを始めてから、DDDを実践するまでの過程
Kazuki Ohashi
March 08, 2018
More Decks by Kazuki Ohashi
See All by Kazuki Ohashi
larave_vue_graphql_supplementation
kzkohashi
1
890
Introduction to using GraphQL for a bit
kzkohashi
0
250
フォロワーがどの雑誌に興味があるのか可視化してみる / magazine-score
kzkohashi
0
730
Amazon Rekognitionを用いてフォロワーの男女比を出す
kzkohashi
1
3k
Other Decks in Technology
See All in Technology
侵入は突然に 〜 IoTマルウェアと悪用される家庭の機器 ~ / When Intrusion Strikes: IoT Malware and the Abuse of Home Devices
nttcom
0
1.6k
JavaScript 研修 (2026)
recruitengineers
PRO
2
530
修正PRを食べてレビュースキルが賢くなる:Claude Codeによる自己改善サイクル
yuyaumetsu
6
1.5k
【CEDEC2026】『ウマ娘 プリティーダービー』 英語版のキャラクターの方言や口調をローカライズするための創造的アプローチ
cygames
PRO
1
240
AWS ネットワーク構築でハマった(ハマりかけた) 5選とそこから得た教訓
nagisa53
4
210
Contract One Engineering Unit 紹介資料
sansan33
PRO
0
19k
その“隠したつもり”が命取り ── 自前と平文をやめて「正解」に委ねる
kuroneko13
0
110
[しろおび夏祭り2026] チャットするAIから、作業するAIへ - 使われ方の変化と、その裏側で起きていること
kk0n
0
1.7k
同じWAFが、攻撃の“形”は弾く── 正当な“形”の不正は通す
kuroneko13
0
170
Cursor Meetup Sapporo - Cursor物語 続編
cocacola917
0
150
[ChatGPT Work LT]事務作業が苦手な人のための バックオフィスの「半」自動化
chimaki_iot
0
280
LLM・AIエージェントシステムベストプラクティス
shibuiwilliam
6
1.1k
Featured
See All Featured
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
Designing Experiences People Love
moore
143
24k
Ethics towards AI in product and experience design
skipperchong
2
340
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
430
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
The Curse of the Amulet
leimatthew05
2
14k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Six Lessons from altMBA
skipperchong
29
4.4k
Side Projects
sachag
455
43k
Faster Mobile Websites
deanohume
310
32k
Transcript
-BSBWFMΛ࢝Ίͯ %%%Λ࣮ફ͢Δ·Ͱ Laravel Meetup Tokyo Vol.10 େڮ Ұथ @kzkohashi
େڮҰथ!L[LPIBTIJ w ΠϯϑϧΤϯαʔϚʔέςΟϯά w αʔόαΠυ ϑϩϯτத৺ w -BSBWFM࢝Ίͯ̍͘Β͍ w %%%ษڧ࢝͠Ίͯϲ݄
%%%ͬͯΔ PS %%%࣮ફͯ͠Δํ
ࠓ͓͢͠Δ͜ͱ -BSBWFMͰ%%%Λ࣮ફ͢Δ·Ͱͷաఔ %%%Λ࣮ફ͢Δ͜ͱͰԿ͕มΘͬͨʁ ٯʹฉ͍ͯΈ͍ͨ
-BSBWFM࢝ΊΔ
͍͍ɻΊͪΌ͍͍ɻ w ͙͢ʹؾ࣋ͪΑ͔͚͘Δ w ཉ͍͠ػೳ͕σϑΥϧτͰ͋Δʢ֦ு͍͢͠ʂʂ w ϥΠϒϥϦ๛ w ຊޠॆ࣮
ॻ͖͍͢ɺઃܭΛ͔ͬ͠Γ͠ͱ͖͍ͨ
%%%Λษڧ࢝͠ΊΔ
͍͍ɻΊͪΌ͍͍ɻ w ݱ࣮ͷؔ৺ΛͰ͖Δ͚ͩ։ൃ্ͱͰγϯΫϩͤ͞Δ w υϝΠϯΤΩεύʔτͱΤϯδχΞͷҰॹʹ͠߹ͬͯϞ σϦϯά͍ͯ͘͠ w ڞ௨ݴޠʢϢϏΩλεݴޠʣͷൃ۷ w ͳΜͲมߋɾվળ͍ͯ͘͠ͷ
֓೦ૉΒ͍͠ʂ
Ͱɺ࣮ફํ๏ʁ
࣮ફͷෑډߴ͍ʁ w ຊಡΉ͚ͩ͡ΌΑ͘Θ͔Βͳ͍ w ࣮ફͯ͠ͳ͕Βͬͯͨ΄͏͕Αͦ͞͏ w 8FCʹ࣮ફ͢ΔͨΊͷ৭ʑͳΞʔΩςΫνϟͳͲ͕͋Δ ௐͨͱ͖ʹΑ͘࠾༻͞Ε͍ͯΔ 3FQPTJUPSZύλʔϯΛಋೖ
$POUSPMMFS 4FSWJDF 3FQPTJUPSZ &MPRVFOU3FQPTJUPSZ .PEFM ϓϨθϯςʔγϣϯ ϏδωεϩδοΫ σʔλૢ࡞ ϏδωεϩδοΫ͔Βσʔλૢ࡞ͷॲཧΛΓ͢ ʢ˞ඞͣͦ͠͏Ͱͳ͍ʣ
ͱ͋ΔαʔϏεͷྫ Ϣʔεέʔε w ϝʔΧʔΞΧϯτΛొ͢Δ w ϝʔΧʔΞΧϯτΛෳ࡞ΕΔ Ϟσϧ
interface MakerAccountRepository { public function getLoginAccountByEmail($email); public function findById($id); public
function register($name, $tel, $email, $password); } 3FQPTJUPSZ ར༻͢ΔࡍͷΠϯλʔϑΣʔε
class EloquentMakerAccountRepository implements MakerAccountRepository { /** @var \App\Models\MakerAccount */ protected
$maker_account; public function __construct(MakerAccount $maker_account) { $this->maker_account = $maker_account; } public function getLoginUserByEmail($email) { return $this->maker_account->whereEmail($email) ->with('maker') ->first(); } public function register($maker_id, …) { $data[‘…’] = $maker_id; … return $this->maker_account->create($data); } } &MPRVFOU3FQPTJUPSZ .PEFMΛ%*
class MakerAccountRegisterService { protected $maker_repo; protected $maker_account_repo; public function __construct(
MakerRepository $maker_repo, MakerAccountRepository $maker_account_repo ) { $this->maker_repo = $maker_repo; $this->maker_account_repo = $maker_account_repo; } protected function register($maker_name,…লུ) { return \DB::transaction(function () use (...লུ) { /** @var \App\Models\Maker $maker */ $maker = $this->maker_repo->register($maker_name, $address); $this->maker_account_repo->register( $maker->id, $staff_name, $tel, $email, $password ); }); } } 4FSWJDF ϦϙδτϦʔΛ௨ͯ͠ొ
Կ͔มΘͬͨʁ w ϏδωεϩδοΫͱσʔλૢ࡞ΛେମΓͤͨ w ݁ہฦ͍ͯ͠Δͷ͕&MPRVFOUͷͨΊɺ֎ଆͰૢ࡞Մೳ σʔλૢ࡞͕౷Ұ͞ΕͯΔ෩ͳͷ͚͕ͩͰ͖ͨ
େ͖ͳצҧ͍ %%%ઃܭͱ͍͏ͷΛΕͣʹ
ΤϯδχΞ૿͑ͨ ਓਓ ˞ϝΠϯ࣮ऀͷ͕Ͳ͔ͬʹ͍·͢ !BJJSP
ࠓ࣮ͦ͜ફ w Կ͔Β࢝ΊͨΒ͍͍ʁ w όϦϡʔΦϒδΣΫτ͔Β࢝ΊͨΒΓ͍͢ͱຢฉ͖ !BJJSP
όϦϡʔΦϒδΣΫτͱʁ w ϓϦϛςΟϒܕͰදݱ͍ͯͨ͠ΛΦϒδΣΫτʹ͢Δ w ࣗͷՃɾఆͳͲͷৼΔ͍Λ࣋ͭ w ΠϛϡʔλϒϧͰ͋Δ
$POUSPMMFS 4FSWJDF 3FQPTJUPSZ &MPRVFOU3FQPTJUPSZ .PEFM ෦తʹ7BMVF0CKFDUʹม υϝΠϯʁ 7BMVF0CKFDU
ͱ͋ΔαʔϏεͷྫ Ϣʔεέʔε w ϝʔΧʔΞΧϯτΛొ͢Δ w ొ͞Ε͍ͯΔϝʔϧ͕ϒϥοΫϦετͷ߹YYY͢Δ Ϟσϧ &NBJMΛ7BMVF0CKFDUʹͯ͠ΈΔ
class Email implements \JsonSerializable { protected $value; protected function __construct(string
$value) { $this->value = $value; } public function value(): string { return $this->value; } public function isBlackList(): boolean { return ($this->value === $blacklist) } public function jsonSerialize() { return $this->value; } } 7BMVF0CKFDU ৼΔ͍Λ࣋ͨͤΔ
class MakerAccount extends Model { protected $table = 'maker_accounts'; protected
$hidden = [ 'id', ]; public function toValueObject() { // Πϛϡʔλϒϧʹ͢ΔͨΊɺreplicate()ͨ݁͠ՌΛฦ٫ $replication = $this->replicate(); $replication->email = new Email($this->email); return $replication; } } .PEFM ରͷ7BMVF0CKFDUΛ٧ΊࠐΉ
class MakerAccountRegisterService { protected $maker_account_repo; public function __construct(MakerAccountRepository $maker_account_repo) {
$this->maker_account_repo = $maker_account_repo; } public function activateEmail($email) { $maker_account = $this->maker_account_repo->findByEmail($email); $maker_account = $maker_account->toValueObject(); return $maker_account->email->isBlackList(); } } 4FSWJDF 7BMVF0CKFDUͷৼΔ͍Λར༻
ײ w 7BMVF0CKFDUͷΈͩͱखܰʹ࢝ΊΒΕΔ w ৼΔ͍Λू͢Δ͜ͱͰΘ͔Γ͘͢ͳͬͨ গͣͭ͠%%%ͷԸܙ͕ड͚ΒΕ͖ͯͨɾɾʁ
৽نαʔϏεͷ։ൃ
ϑϧͰ%%%ͷ࣮ફ νϟϯεʂ IUUQTHJUIVCDPNTIJOYMBSBWFMEEETBNQMF ৽ݪ͞ΜͷΊͪΌͪ͘Όࢀߟʹͯ͠·͢
ΤϯςΟςΟͱ w ҰҙʹࣝผՄೳͳΦϒδΣΫτ w ෳͷΦϒδΣΫτৼΔ͍Λ͍࣋ͬͯΔ w ৼΔ͍͕গͳ͍߹ݕ౼͖͢
$POUSPMMFS 6TF$BTF 3FQPTJUPSZ &MPRVFOU3FQPTJUPSZ .PEFM υϝΠϯ &OUJUZΛฦ͢ 7BMVF0CKFDU &OUJUZ
ͱ͋ΔαʔϏεͷྫ Ϣʔεέʔε w ը໘͔ΒϝʔΧʔ͕ ࣗͷ ΞΧϯτҰཡӾཡ͢Δ w ϝʔΧʔͷΞΧϯτͷҰཡΛϖʔδωʔγϣϯͰฦ͢ Ϟσϧ ϞσϧΛ&OUJUZʹͯ͠ΈΔ
class MakerAccount implements \Arrayable { /** @var MakerId */ protected
$maker_id; protected $name; protected $tel; protected $email; protected $password; public function __construct(MakerId $maker_id,…লུ) { $this->maker_id = $maker_id; $this->email = $email; if ($password) { $this->password = MakerAccountPassword::of(\Hash::make($password->value())); } } public function toArray() { $array = []; $class_vars = array_keys(get_class_vars(static::class)); foreach ($class_vars as $var_name) { $array[$var_name] = $this->{$var_name}; } return $array; } } &OUJUZ ֤7BMVF0CKFDUΛ٧ΊࠐΉ
class MakerAccount extends Model implements Domainable { public function maker()
{ return $this->belongsTo(Maker::class); } /** * @return \App\Domains\Entities\MakerAccount */ public function toDomain() { return new Entities\MakerAccount( MakerId::of($this->maker_id), MakerAccountName::of($this->name), MakerAccountTel::of($this->tel), MakerAccountEmail::of($this->email) ); } } .PEFM &OUJUZʹม
class DomainServiceProvider extends ServiceProvider { … protected function collectionMacro() {
Builder::macro('toDomainCollection', function () { /** @noinspection PhpUndefinedMethodInspection */ return $this->get()->map(function (Domainable $model) { return $model->toDomain(); }); }); Collection::macro('toDomainCollection', function () { /** @noinspection PhpUndefinedMethodInspection */ return $this->map(function (Domainable $model) { return $model->toDomain(); }); }); } protected function paginateMacro() { … } } $PMMFDUJPO #VJMEFS͔Β%PNBJOͷྻΛฦ͢.BDSPΛՃ
class FetchMakerAccountList { protected $maker_account_repo; public function __construct(MakerAccountRepository $maker_account_repo) {
$this->maker_account_repo = $maker_account_repo; } protected function common(MakerAccountId $maker_account_id) { return $this->maker_account_repo->findByMakerIdAsModel($maker_id); } public function asCollection(MakerId $maker_id) { return $this->common($maker_id)->toDomainCollection(); } public function asPaginate(MakerId $maker_id) { return $this->common($maker_id)->domainPaginate(); } } 6TF$BTF ೋͭͷৼΔ͍Λ࣋ͨͤͯͨ
class MakerAccountController extends Controller { public function index(FetchMakerAccountList $usecase) {
$maker_accounts = $usecase->asPaginate(MakerId::of(auth()->maker->id())); return response()->json($maker_accounts); } } $POUSPMMFS ར༻
6TF$BTFʹෳͷৼΔ͍ͨͤͯ͠·͍ͬͯΔ 6TF$BTFͷमਖ਼
;Ή;Ή 6TF$BTFͷमਖ਼
class FetchMakerAccountPaginate { protected $maker_account_repo; public function __construct(MakerAccountRepository $maker_account_repo) {
$this->maker_account_repo = $maker_account_repo; } public function __invoke(MakerAccountId $maker_account_id) { return $this->maker_account_repo ->findByMakerIdAsModel($maker_id) ->domainPaginate(); } } 6TF$BTFʢमਖ਼ޙʣ ҰͭͷৼΔ͍ͷΈʹ੍ݶ
class MakerAccountController extends Controller { public function index(FetchMakerAccountList $usecase) {
$maker_accounts = $usecase(MakerId::of(auth()->maker->id())); return response()->json($maker_accounts); } } $POUSPMMFS ར༻
ࠓ͓ͨ͜͠ͱ -BSBWFMͰ%%%Λ࣮ફ͢Δ·Ͱͷաఔ %%%Λ࣮ફ͢Δ͜ͱͰԿ͕มΘͬͨʁ ҰͰແཧͰɺগͣͭ͠ͳΒ࣮ફͰ͖Δ ༷ͷѲ͕͘͢͠ͳͬͨ ϏδωεαΠυͱͷೝ͕ࣝͱΓ͘͢ͳͬͨ ઃܭ ࣮ ྑ͍ϧʔϓ
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠
ฉ͖͍ͨ͜ͱ w &OUJUZ͕&OUJUZΛ࣋ͭ߹ͷύϑΥʔϚϯεͷ w όϦσʔγϣϯͲ͜Ͱ࣋ͨͤΔ͖͔ w ࣮ࡍͬͯΈͯɺԿ͕ྑ͔ͬͨͷ͔