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
1
1.8k
Laravelを始めて DDDを実践するまで
Laravelを始めてから、DDDを実践するまでの過程
Kazuki Ohashi
March 08, 2018
Tweet
Share
More Decks by Kazuki Ohashi
See All by Kazuki Ohashi
larave_vue_graphql_supplementation
kzkohashi
1
770
Introduction to using GraphQL for a bit
kzkohashi
0
210
フォロワーがどの雑誌に興味があるのか可視化してみる / magazine-score
kzkohashi
0
550
Amazon Rekognitionを用いてフォロワーの男女比を出す
kzkohashi
1
2.6k
Other Decks in Technology
See All in Technology
Azure Container Apps + Bicep 〜 こんな感じで運用しています
kaz29
2
470
ワールドカフェI /チューターを改良する / World Café I and Improving the Tutors
ks91
PRO
0
120
Cloud Native Java with Spring Boot (CNCF Aarhus, April 2024)
thomasvitale
1
170
Janus
bkuhlmann
1
490
よく聞くけど使ったことないソフトウェアNo.1 KafkaとSnowflake
foursue
4
360
私が trocco を推す理由
__allllllllez__
1
220
元インフラエンジニアに成る / Human Resources to Human Relations
bobtani
4
920
ここが嬉しいABAC ここが辛いよABAC #再解説+補足編
masahirokawahara
1
270
MapLibreとAmazon Location Service
dayjournal
1
150
LangSmith入門―トレース/評価/プロンプト管理などを担うLLMアプリ開発プラットフォーム
os1ma
3
140
JAWS-UG Bedrock Claude Night
yamahiro
3
600
リテール金融(キャッシュレス・ネット銀行・ネット証券)の競争環境と経済圏
8maki
0
1.1k
Featured
See All Featured
Design by the Numbers
sachag
274
18k
A Tale of Four Properties
chriscoyier
151
22k
Fontdeck: Realign not Redesign
paulrobertlloyd
76
4.9k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
78
42k
The Invisible Customer
myddelton
114
12k
Infographics Made Easy
chrislema
238
18k
The Invisible Side of Design
smashingmag
294
49k
Rails Girls Zürich Keynote
gr2m
91
13k
RailsConf 2023
tenderlove
4
540
Unsuck your backbone
ammeep
663
57k
Building a Scalable Design System with Sketch
lauravandoore
456
32k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
40
4.4k
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 ࣮ࡍͬͯΈͯɺԿ͕ྑ͔ͬͨͷ͔