SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

IDDD本から理解するドメイン駆動設計

実践DDD本 第12章「リポジトリ」~集約の永続化管理を担当~

IDDD本から理解するドメイン駆動設計 第12回

  • X ポスト
  • このエントリーをはてなブックマークに追加

永続指向のリポジトリ

 最後に「永続指向のリポジトリ」のコードについて紹介します。先ほど紹介した通り、永続指向は対象ストレージがNoSQLなどのキーバーリューストアの時に使用し、集約の情報全体をまとめて保存します。インターフェイス(JavaC#)は次の通りです。

[リスト]「永続指向リポジトリ」の公開インターフェイス(Java)
// ■プロダクト集約を管理するリポジトリ
public interface ProductRepository {

    // ▼プロダクト集約を取得(テナントID+プロダクトID)
    public Product productOfId(TenantId aTenantId, ProductId aProductId);

    // ▼リポジトリに保存
    public void save(Product aProduct);

    // ▼リポジトリから削除
    public void remove(Product aProduct);
~中略~
}

 集約全体をMongoDBやLevelDBの1つのレコード(ドキュメント)として保存するため、AddメソッドではなくSaveメソッドを使います。それ以外はコレクション指向のインターフェイス設計と同じです。

永続指向のリポジトリ実装クラス

 続けて、実装クラスのコード(Java)を見てみましょう。ここではNoSQLのひとつであるLevelDBによる実装となっています。

[リスト]「永続指向リポジトリ」の実装クラス(Java)
// ■LevelDBでの実装リポジトリ
public class LevelDBProductRepository
        extends AbstractLevelDBRepository implements ProductRepository {

    private static final String PRIMARY = "PRODUCT#PK";

    // ▼コンストラクタで、DBの場所として、コンテキスト名を使用
    public LevelDBProductRepository() {
        super(LevelDBDatabasePath.agilePMPath());
    }

    // ▼プロダクト集約を取得(テナントID+プロダクトID)
    @Override
    public Product productOfId(TenantId aTenantId, ProductId aProductId) {
        // 取得に使うキーを設定する
        LevelDBKey primaryKey =
            new LevelDBKey(PRIMARY, aTenantId.id(), aProductId.id());
        Product product =
                LevelDBUnitOfWork.readOnly(this.database())
                    .readObject(primaryKey.key().getBytes(), Product.class);
        return product;
    }

    // ▼プロダクトをリポジトリに保存
    @Override
    public void save(Product aProduct) {
        LevelDBKey lockKey = new LevelDBKey(PRIMARY, aProduct.tenantId().id());
        LevelDBUnitOfWork uow = LevelDBUnitOfWork.current();
        uow.lock(lockKey.key());
        this.save(aProduct, uow);
    }
~中略~
}

 ここではLevelDBに対する保存/削除/取得処理を記述しています。NoSQLでは、データの格納と取得のために一意なキーの設計が必要です。IDDD本では「境界づけられたコンテキストの短縮名」「集約の名前」「一意な識別子」を組み合わせる案を提示しています。

 このプロダクトという集約の例であれば、まずDBそのものをコンテキスト名(LevelDBDatabasePath.agilePMPathの部分)にて分離し、それ以外の集約を示す定数「PRODUCT#PK」と一意な識別子「テナントID」+「プロダクトID」の組み合わせをキーとして使用しています。

 以上、永続指向によるリポジトリの実装方法について紹介しました。

最後に

 本稿ではDDDにおけるリポジトリについて紹介しました。集約の永続化を管理するにあたって、いくつかの設計指針、実装パターンがあることが理解できたと思います。次回の第13回では「境界づけられたコンテキストの結合」について紹介します。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
IDDD本から理解するドメイン駆動設計連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 青木 淳夫(アオキ アツオ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/11048 2018/09/10 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング