僕はドメイン駆動設計が理解できない。

Twitter ツイート Hatena Bookmark ブックマーク

設計やオブジェクト指向は理解したつもりなのに、実は違うというような事の繰り返しのような気もしますが、それにしても僕はなにも理解できていないんですよね。

DomainKataを少し使って理解した気になっていんですが、ただの勘違いでした・・・。

DDDを解ったつもりになっていて、すごく恥ずかしくて、すごく悔しくて、毎日悩んでいます。
だから、今わからない事をこの記事に残しておこうと思いました。

たとえばカテゴリ一覧を表示するということに関して

カテゴリ一覧を表示するページなんてのWebアプリによくある実装内容だと思います。
このような場合どうしたらいいのか悩んでいます。

エンティティの候補として

  • カテゴリ
  • カテゴリ一覧(コレクション的な)

このような感じになるかと思います。

カテゴリ一覧ってサービスじゃないの?

「カテゴリ一覧」をエンティティとして表現するのはありかと思います。
しかし、カテゴリ一覧はサービスでもいいのではないかと思います。
一覧を取得するという動作なので、エンティティとして表現するよりサービスとして表現したほうがいいのでは?と考えてました。
「指定した日付以前のカテゴリしか表示しない」みたいな制約が後から追加されたとしても、サービスクラスに処理を追加できますよね?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?php

class CategoryListService
{
  /**
   *
   * @var CategoryRepository
   */
  private $repository;

  public function __construct(EntityRepository $repository)
  {
      $this->repository = $repository;
  }

  public function run()
  {
    return $this->repository->findAll();
  }
}

しかし、この考え方はどこか違和感を感じます。
それは、findAll()だけなのに、サービスクラスにするのは過剰な実装ではないのか?と思い、違和感を感じているのだと思います。

コレクション的なエンティティとして一覧を表現すればいいのでは?

サービスクラスにするのが過剰だから、コレクション的なアプローチを考えてみようと思います。
リポジトリクラスに定義したfindCategoryListメソッドを実行したら、コレクションが取れるような仕組みはどうなのかなぁーと。
検索時の条件が発生したらfindCategoryListに何らかの処理を追加したり、取得した値から何かしらの制約をかけるの場合はCategoryCollectionに何らかのロジックを追加すればいいのかなと考えています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Entity
<?php
class CategoryCollection implements \IteratorAggregate
{
  private $categories;

  public function __construct(array $categories = [])
  {
    $this->categories = $categories;
  }

  public function getIterator()
  {
    return new \ArrayIterator($this->categories);
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// Repository
<?php
class CategoryRepository extends EntityRepository
{
  public function findCategoryList()
  {
      return new CategoryCollection($this->findAll());
  }

}

このような考え方もありかとは思いますが、現状ただ「取得する」という事以外なにもないので、やはりこれも過剰なのでは?って思ってしまうんですよね。

一覧を取得するだけなら、アプリケーションからの要求であってビジネスロジックが含まれないのでは?

ビジネスロジックの定義を正しく理解できていないのですが、一覧を取得するという事に特にビジネスロジックはないのでは?って考えてしまうんですよね。
それならば、別にfindAll()をなんの意識もせずにコントローラから実行してあげればいいじゃないの?って思うんですよね。

まとめ

こんな感じで毎日悩んでいます。
「実装からの視点でばかり考えすぎているのかな?」って思っています。
「サービスにするのも、コレクションなエンティティにするのも、モデリングした結果として、どちらかになるのでは?」とも思いますが、今の僕にはなにが正しいのかとか、どう判断するべきかわかりません。

DDD本も全て読めているわけでもないので、ちゃんとDDD本を読んだり、他の資料などを読んで勉強しようと思っていますが、現状の僕は、このような事で悩んでいるわけです。
おやすみなさい。

comments powered by Disqus
Built with Hugo
テーマ StackJimmy によって設計されています。