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

PofEAAで読み解くDoctrine2

男爵
June 16, 2018

 PofEAAで読み解くDoctrine2

PHPカンファレンス福岡2018の15分枠の発表資料です。

2018.06.19 口頭で説明した内容を追記

男爵

June 16, 2018
Tweet

More Decks by 男爵

Other Decks in Programming

Transcript

  1. PofEAAで読み解く
    Doctrine2
    @dnskimox

    View Slide

  2. 自己紹介
    ⊡ 本名:丹賀健一
    ⊡ 通称:男爵
    ⊡ dnskimo
    ⊡ dnskimox
    ⊡ 北海道在住
    ⊡ 株式会社インフィニットループ
    ⊡ ソシャゲバックエンドAPI開発

    View Slide

  3. 宣伝のやつ
    https://www.infiniteloop.co.jp/blog/2018/06/seventeenth/

    View Slide

  4. P of EAA
    https://ja.wikipedia.org/wiki/マーティン・ファウ
    ラー
    ⊡ 原題『Patterns of Enterprise
    Application Architecture』
    ⊡ マーティン・ファウラー著
    ⊡ エンタープライズアプリケーションの
    ための設計パターン集

    View Slide

  5. エンタープライズアプリケーションと
    は?
    1. データを永続化する
    2. 大量のデータを扱う
    3. 同時に多数のリクエストを受けつける
    4. 他のエンタープライズアプリケーションと連携する

    View Slide

  6. エンタープライズアプリケーションと
    は?
    P of EAA ≒ WEBアプリケーションのための設
    計パターン集

    View Slide

  7. Catalog of P of EAA
    ⊡ Domain Model
    ⊡ Active Record
    ⊡ Data Mapper
    ⊡ Unit of Work
    ⊡ Identity Map
    ⊡ Metadata Mapping
    ⊡ Foreign Key Mapping
    ⊡ Lazy Load
    ⊡ Single Table Inheritance
    ⊡ Repository
    ⊡ Model View Controller
    ⊡ Front Controller
    ⊡ Remote Facade
    ⊡ Service Layer
    ⊡ Data Transfer Object
    ⊡ Optimistic Offline Lock
    ⊡ Layer Supertype
    ⊡ Separated Interface
    ⊡ Value Object
    ⊡ etc...

    View Slide

  8. Doctrine2
    ⊡ Data Mapperパターンを採用したORM
    ⊡ Symfony Standard Editionに同梱
    ⊡ Doctrine2単独で使うことも可能

    View Slide

  9. 架空のActive Record

    View Slide

  10. 関心事多すぎ?
    Characterクラスの関心事
    ⊡ 自身が保有するデータ
    ⊡ ドメインロジック
    ⊡ 自身の状態をDBに反映する方法
    ⊡ DBから自身を復元する方法

    View Slide

  11. 関心の分離ができたら……
    Characterクラスの関心事
    ⊡ 自身が保有するデータ
    ⊡ ドメインロジック
    ???の関心事
    ⊡ オブジェクトの状態をDBに
    反映する方法
    ⊡ DBからオブジェクトを復元
    する方法

    View Slide

  12. Data Mapper
    オブジェクトとデータベースを分離する

    View Slide


  13. A layer of Mappers that moves data between
    objects and a database while keeping them
    independent of each other and the mapper
    itself.

    View Slide

  14. Doctrine2のData Mapperのイメージ

    View Slide

  15. 登場人物紹介

    View Slide

  16. Entity
    ⊡ 永続化されるオブジェクト
    ⊡ 一意な識別子を持つ
    ⊡ Plain Old PHP Object

    View Slide

  17. ClassMetadata
    ⊡ エンティティとテーブルを対
    応付けるための地図
    ⊡ エンティティ同士の関係図

    View Slide

  18. Persister
    ⊡ DBにデータを保存する
    ⊡ DBからデータを取り出す
    ⊡ SQLを組み立てる

    View Slide

  19. Hyderator
    ⊡ DBから取り出したデータか
    らエンティティを復元する
    ⊡ 乾燥保存されたデータに水
    を与える(Hydrate)

    View Slide

  20. Repository
    ⊡ エンティティ検索のためのコ
    レクション風のインター
    フェースを提供
    ⊡ アプリケーション側の拡張ポ
    イント

    View Slide

  21. UnitOfWork
    ⊡ エンティティを監視し、その
    変化を記録する
    ⊡ 詳細は後述

    View Slide

  22. EntityManager
    ⊡ データマッパーオブジェクト達
    の窓口役(Facade)
    ⊡ データマッパーオブジェクト間
    の調停者(Mediator)

    View Slide

  23. How It Works

    View Slide

  24. CRUDのC
    $em = EntityManager::create(...);
    $character = new Character();
    $character->setName(“Bob”);
    $em->persist($character);
    $em->flush();
    // Executed SQL: INSERT INTO characters (name) VALUES(‘Bob’);

    View Slide

  25. CRUDのCの舞台裏(1)

    View Slide

  26. CRUDのCの舞台裏(2)

    View Slide

  27. CRUDのR
    $em = EntityManager::create(...);
    $characterRepository = $em->getRepository(Character::class);
    $character = $characterRepository->find(1);
    // Executed SQL: SELECT FROM characters WHERE id = 1;
    $characters = $characterRepository->findByName(“Bob”);
    // Executed SQL: SELECT FROM characters WHERE name = ‘Bob’;
    $characters = $characterRepository->findAll();
    // Executed SQL: SELECT FROM characters;

    View Slide

  28. CRUDのRの舞台裏

    View Slide

  29. 経験値獲得メソッド
    class Character...
    public function gainExp(int $exp)
    {
    assert(0 < $exp);
    $this->setExp($this->getExp() + $exp);
    // 以下レベルアップ判定など
    ...
    }
    }

    View Slide

  30. CRUDのU
    $em = EntityManager::create(...);
    $characterRepository = $em->getRepository(Character::class);
    $character = $characterRepository->find(1);
    // Executed SQL: SELECT FROM characters WHERE id = 1;
    $character->gainExp(100);
    $em->flush();
    // Executed SQL: UPDATE characters SET exp = 100 WHERE id = 1;

    View Slide

  31. Unit of Work
    オブジェクトを追跡し、その変化を書き出す

    View Slide


  32. Maintains a list of objects affected by a
    business transaction and coordinates the
    writing out of changes and the resolution of
    concurrency problems.

    View Slide

  33. How It Works

    View Slide

  34. UnitOfWorkの暗躍
    Rで密かにやっていたこと
    ⊡ エンティティを監視下に置く
    ⊡ エンティティのオリジナルデー
    タを保持する
    Uでやること
    ⊡ 現在のエンティティとオリジ
    ナルデータを比較する
    ⊡ 差分があったらPersisterに
    更新を依頼する

    View Slide

  35. CRUDのUの舞台裏(1)

    View Slide

  36. CRUDのUの舞台裏(2)

    View Slide

  37. ロストアップデートの予感……
    $character1A = $characterRepository->find(1);
    // Executed SQL: SELECT FROM characters WHERE id = 1;
    $character1B = $characterRepository->find(1);
    // Executed SQL?: SELECT FROM characters WHERE id = 1;
    $character1A->gainExp(100);
    $character1B->gainExp(100);
    $em->flush();
    // Executed SQL?: UPDATE characters SET exp = 100 WHERE id = 1;
    // Executed SQL?: UPDATE characters SET exp = 100 WHERE id = 1;

    View Slide

  38. Identity Map
    メモリ上のオブジェクトを一意にする

    View Slide


  39. Ensures that each object gets loaded only
    once by keeping every loaded object in a map.
    Looks up objects using the map when
    referring to them.

    View Slide

  40. How It Works

    View Slide

  41. 真・CRUDのRの舞台裏(1)

    View Slide

  42. 真・CRUDのRの舞台裏(2)

    View Slide

  43. ロストアップデートは起きない
    $character1A = $characterRepository->find(1);
    // Executed SQL: SELECT FROM characters WHERE id = 1;
    $character1B = $characterRepository->find(1);
    // Executed SQL: NONE
    $character1A->gainExp(100);
    $character1B->gainExp(100);
    $em->flush();
    // Executed SQL: UPDATE characters SET exp = 200 WHERE id = 1;

    View Slide

  44. CRUDのDについ
    ては割愛

    View Slide

  45. その他Doctrine2で使われているパ
    ターン
    ⊡ Domain Model
    ⊡ Active Record
    ⊡ Data Mapper
    ⊡ Unit of Work
    ⊡ Identity Map
    ⊡ Metadata Mapping
    ⊡ Foreign Key Mapping
    ⊡ Lazy Load
    ⊡ Single Table Inheritance
    ⊡ Repository
    ⊡ Model View Controller
    ⊡ Front Controller
    ⊡ Remote Facade
    ⊡ Service Layer
    ⊡ Data Transfer Object
    ⊡ Optimistic Offline Lock
    ⊡ Layer Supertype
    ⊡ Separated Interface
    ⊡ Value Object
    ⊡ etc...

    View Slide

  46. Let’s Doctrine!

    View Slide

  47. 参考文献
    ⊡ Patterns of Enterprise Application Architecture
    ⊡ Catalog of Patterns of Enterprise Application Architecture
    ⊡ Data Mapper
    ⊡ Unit of Work
    ⊡ Identity Map
    ⊡ POJO

    View Slide