$30 off During Our Annual Pro Sale. View Details »

Laravelを始めて DDDを実践するまで

Laravelを始めて DDDを実践するまで

Laravelを始めてから、DDDを実践するまでの過程

Kazuki Ohashi

March 08, 2018
Tweet

More Decks by Kazuki Ohashi

Other Decks in Technology

Transcript

  1. -BSBWFMΛ࢝Ίͯ
    %%%Λ࣮ફ͢Δ·Ͱ

    Laravel Meetup Tokyo Vol.10
    େڮ Ұथ @kzkohashi

    View Slide

  2. େڮҰथ!L[LPIBTIJ
    w ΠϯϑϧΤϯαʔϚʔέςΟϯά
    w αʔόαΠυ ϑϩϯτத৺
    w -BSBWFM࢝Ίͯ̍೥͘Β͍
    w %%%͸ษڧ࢝͠Ίͯ਺ϲ݄

    View Slide

  3. %%%஌ͬͯΔ
    PS
    %%%࣮ફͯ͠Δํ

    View Slide

  4. ࠓ೔͓࿩͢͠Δ͜ͱ
    -BSBWFMͰ%%%Λ࣮ફ͢Δ·Ͱͷաఔ
    %%%Λ࣮ફ͢Δ͜ͱͰԿ͕มΘͬͨʁ
    ٯʹฉ͍ͯΈ͍ͨ

    View Slide


  5. -BSBWFM࢝ΊΔ

    View Slide

  6. ͍͍ɻΊͪΌ͍͍ɻ
    w ͙͢ʹؾ࣋ͪΑ͔͚͘Δ
    w ཉ͍͠ػೳ͕σϑΥϧτͰ͋Δʢ֦ு͠΍͍͢ʂʂ

    w ϥΠϒϥϦ๛෋
    w ೔ຊޠॆ࣮
    ॻ͖΍͍͢෼ɺઃܭΛ͔ͬ͠Γ͠ͱ͖͍ͨ

    View Slide

  7. %%%Λษڧ࢝͠ΊΔ

    View Slide

  8. ͍͍ɻΊͪΌ͍͍ɻ
    w ݱ࣮ͷؔ৺ΛͰ͖Δ͚ͩ։ൃ্ͱͰγϯΫϩͤ͞Δ
    w υϝΠϯΤΩεύʔτͱΤϯδχΞͷҰॹʹ࿩͠߹ͬͯϞ
    σϦϯά͍ͯ͘͠
    w ڞ௨ݴޠʢϢϏΩλεݴޠʣͷൃ۷
    w ͳΜͲ΋มߋɾվળ͍ͯ͘͠΋ͷ

    View Slide

  9. ֓೦͸ૉ੖Β͍͠ʂ

    View Slide

  10. Ͱɺ࣮ફํ๏͸ʁ

    View Slide

  11. ࣮ફͷෑډ͸ߴ͍ʁ
    w ຊಡΉ͚ͩ͡ΌΑ͘Θ͔Βͳ͍
    w ࣮ફͯ͠ͳ͕Β΍ͬͯͨ΄͏͕Αͦ͞͏
    w 8FCʹ͸࣮ફ͢ΔͨΊͷ৭ʑͳΞʔΩςΫνϟͳͲ͕͋Δ
    ௐ΂ͨͱ͖ʹΑ͘࠾༻͞Ε͍ͯΔ
    3FQPTJUPSZύλʔϯΛಋೖ

    View Slide

  12. $POUSPMMFS
    4FSWJDF
    3FQPTJUPSZ
    &MPRVFOU3FQPTJUPSZ .PEFM
    ϓϨθϯςʔγϣϯ
    ϏδωεϩδοΫ
    σʔλૢ࡞
    ϏδωεϩδοΫ͔Βσʔλૢ࡞ͷॲཧΛ੾Γ཭͢

    ʢ˞ඞͣ͠΋ͦ͏Ͱͳ͍ʣ

    View Slide

  13. ͱ͋ΔαʔϏεͷྫ
    Ϣʔεέʔε
    w ϝʔΧʔ͸ΞΧ΢ϯτΛొ࿥͢Δ
    w ϝʔΧʔ͸ΞΧ΢ϯτΛෳ਺࡞ΕΔ
    Ϟσϧ

    View Slide

  14. interface MakerAccountRepository
    {
    public function getLoginAccountByEmail($email);
    public function findById($id);
    public function register($name, $tel, $email, $password);
    }
    3FQPTJUPSZ
    ར༻͢ΔࡍͷΠϯλʔϑΣʔε

    View Slide

  15. 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Λ%*

    View Slide

  16. 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
    ϦϙδτϦʔΛ௨ͯ͠ొ࿥

    View Slide

  17. Կ͔มΘͬͨʁ
    w ϏδωεϩδοΫͱσʔλૢ࡞Λେମ੾Γ཭ͤͨ
    w ݁ہฦ͍ͯ͠Δͷ͕&MPRVFOUͷͨΊɺ֎ଆͰૢ࡞Մೳ
    σʔλૢ࡞͕౷Ұ͞ΕͯΔ෩ͳ΋ͷ͚͕ͩͰ͖ͨ

    View Slide

  18. େ͖ͳצҧ͍
    %%%͸ઃܭͱ͍͏ͷΛ๨Εͣʹ

    View Slide

  19. ΤϯδχΞ૿͑ͨ
    ਓਓ
    ˞ϝΠϯ࣮૷ऀͷ͕Ͳ͔ͬʹ͍·͢
    !BJJSP

    View Slide

  20. ࠓ౓࣮ͦ͜ફ
    w Կ͔Β࢝ΊͨΒ͍͍ʁ
    w όϦϡʔΦϒδΣΫτ͔Β࢝ΊͨΒ΍Γ΍͍͢ͱຢฉ͖
    !BJJSP

    View Slide

  21. όϦϡʔΦϒδΣΫτͱ͸ʁ
    w ϓϦϛςΟϒܕͰදݱ͍ͯͨ͠஋ΛΦϒδΣΫτʹ͢Δ
    w ࣗ਎ͷՃ޻ɾ൑ఆͳͲͷৼΔ෣͍Λ࣋ͭ
    w ΠϛϡʔλϒϧͰ͋Δ

    View Slide

  22. $POUSPMMFS
    4FSWJDF
    3FQPTJUPSZ
    &MPRVFOU3FQPTJUPSZ .PEFM
    ෦෼తʹ7BMVF0CKFDUʹม׵
    υϝΠϯ૚ʁ
    7BMVF0CKFDU

    View Slide

  23. ͱ͋ΔαʔϏεͷྫ
    Ϣʔεέʔε
    w ϝʔΧʔ͸ΞΧ΢ϯτΛొ࿥͢Δ
    w ొ࿥͞Ε͍ͯΔϝʔϧ͕ϒϥοΫϦετͷ৔߹YYY͢Δ
    Ϟσϧ &NBJMΛ7BMVF0CKFDUʹͯ͠ΈΔ

    View Slide

  24. 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
    ৼΔ෣͍Λ࣋ͨͤΔ

    View Slide

  25. 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Λ٧ΊࠐΉ

    View Slide

  26. 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ͷৼΔ෣͍Λར༻

    View Slide

  27. ײ૝
    w 7BMVF0CKFDUͷΈͩͱखܰʹ࢝ΊΒΕΔ
    w ৼΔ෣͍Λू໿͢Δ͜ͱͰΘ͔Γ΍͘͢ͳͬͨ
    গͣͭ͠%%%ͷԸܙ͕ड͚ΒΕ͖ͯͨɾɾʁ

    View Slide


  28. ৽نαʔϏεͷ։ൃ

    View Slide

  29. ϑϧͰ%%%ͷ࣮ફ
    νϟϯεʂ
    IUUQTHJUIVCDPNTIJOYMBSBWFMEEETBNQMF
    ৽ݪ͞ΜͷΊͪΌͪ͘Όࢀߟʹͯ͠·͢

    View Slide

  30. ΤϯςΟςΟͱ͸
    w ҰҙʹࣝผՄೳͳΦϒδΣΫτ
    w ෳ਺ͷ஋ΦϒδΣΫτ΍ৼΔ෣͍Λ͍࣋ͬͯΔ
    w ৼΔ෣͍͕গͳ͍৔߹͸ݕ౼͢΂͖

    View Slide

  31. $POUSPMMFS
    6TF$BTF
    3FQPTJUPSZ
    &MPRVFOU3FQPTJUPSZ .PEFM
    υϝΠϯ૚
    &OUJUZΛฦ͢
    7BMVF0CKFDU &OUJUZ

    View Slide

  32. ͱ͋ΔαʔϏεͷྫ
    Ϣʔεέʔε
    w ը໘͔ΒϝʔΧʔ͕ ࣗ਎ͷ
    ΞΧ΢ϯτҰཡӾཡ͢Δ
    w ϝʔΧʔͷΞΧ΢ϯτͷҰཡΛϖʔδωʔγϣϯͰฦ͢
    Ϟσϧ
    ϞσϧΛ&OUJUZʹͯ͠ΈΔ

    View Slide

  33. 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Λ٧ΊࠐΉ

    View Slide

  34. 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ʹม׵

    View Slide

  35. 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Λ௥Ճ

    View Slide

  36. 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
    ೋͭͷৼΔ෣͍Λ࣋ͨͤͯͨ

    View Slide

  37. class MakerAccountController extends Controller
    {
    public function index(FetchMakerAccountList $usecase)
    {
    $maker_accounts = $usecase->asPaginate(MakerId::of(auth()->maker->id()));
    return response()->json($maker_accounts);
    }
    }
    $POUSPMMFS
    ར༻

    View Slide

  38. 6TF$BTFʹෳ਺ͷৼΔ෣͍΋ͨͤͯ͠·͍ͬͯΔ
    6TF$BTFͷमਖ਼

    View Slide

  39. ;Ή;Ή
    6TF$BTFͷमਖ਼

    View Slide

  40. 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ʢमਖ਼ޙʣ
    ҰͭͷৼΔ෣͍ͷΈʹ੍ݶ

    View Slide

  41. class MakerAccountController extends Controller
    {
    public function index(FetchMakerAccountList $usecase)
    {
    $maker_accounts = $usecase(MakerId::of(auth()->maker->id()));
    return response()->json($maker_accounts);
    }
    }
    $POUSPMMFS
    ར༻

    View Slide

  42. ࠓ೔͓࿩ͨ͜͠ͱ
    -BSBWFMͰ%%%Λ࣮ફ͢Δ·Ͱͷաఔ
    %%%Λ࣮ફ͢Δ͜ͱͰԿ͕มΘͬͨʁ
    Ұ౓Ͱ͸ແཧͰ΋ɺগͣͭ͠ͳΒ࣮ફͰ͖Δ
    ࢓༷ͷ೺Ѳ͕͠΍͘͢ͳͬͨ
    ϏδωεαΠυͱͷೝ͕ࣝͱΓ΍͘͢ͳͬͨ
    ઃܭ ࣮૷
    ྑ͍ϧʔϓ

    View Slide

  43. ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide

  44. ฉ͖͍ͨ͜ͱ
    w &OUJUZ͕&OUJUZΛ࣋ͭ৔߹ͷύϑΥʔϚϯεͷ໰୊఺
    w όϦσʔγϣϯ͸Ͳ͜Ͱ࣋ͨͤΔ΂͖͔
    w ࣮ࡍ΍ͬͯΈͯɺԿ͕ྑ͔ͬͨͷ͔

    View Slide