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
2
1.9k
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
850
Introduction to using GraphQL for a bit
kzkohashi
0
220
フォロワーがどの雑誌に興味があるのか可視化してみる / magazine-score
kzkohashi
0
670
Amazon Rekognitionを用いてフォロワーの男女比を出す
kzkohashi
1
2.9k
Other Decks in Technology
See All in Technology
クラウドとリアルの融合により、製造業はどう変わるのか?〜クラスメソッドの製造業への取組と共に〜
hamadakoji
0
390
Kubernetes self-healing of your workload
hwchiu
0
460
「タコピーの原罪」から学ぶ間違った”支援” / the bad support of Takopii
piyonakajima
0
140
OCIjp_Oracle AI World_Recap
shinpy
1
170
ソフトウェアエンジニアの生成AI活用と、これから
lycorptech_jp
PRO
0
880
Digitization部 紹介資料
sansan33
PRO
1
5.7k
Biz職でもDifyでできる! 「触らないAIワークフロー」を実現する方法
igarashikana
7
3.2k
Introdução a Service Mesh usando o Istio
aeciopires
1
280
Okta Identity Governanceで実現する最小権限の原則 / Implementing the Principle of Least Privilege with Okta Identity Governance
tatsumin39
0
170
Introduction to Sansan for Engineers / エンジニア向け会社紹介
sansan33
PRO
5
43k
Zephyr(RTOS)にEdge AIを組み込んでみた話
iotengineer22
1
320
初めてのDatabricks Apps開発
taka_aki
1
280
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
340
57k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.2k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Building a Scalable Design System with Sketch
lauravandoore
463
33k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
Scaling GitHub
holman
463
140k
The World Runs on Bad Software
bkeepers
PRO
72
11k
Intergalactic Javascript Robots from Outer Space
tanoku
272
27k
The Language of Interfaces
destraynor
162
25k
Embracing the Ebb and Flow
colly
88
4.9k
Making the Leap to Tech Lead
cromwellryan
135
9.6k
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 ࣮ࡍͬͯΈͯɺԿ͕ྑ͔ͬͨͷ͔