在实际项目中实施DDD的步骤

时间:2015-03-19 09:43:08

标签: domain-driven-design use-case

在引入域驱动设计之后,我意识到DDD专注于业务模型,而不是任何特定的框架/语言/技术。作为数据驱动型思维持有者(x),我正在努力确定在我们的实际项目中实施DDD的步骤。我想知道现实世界DDD实现中的实际步骤是什么。例如:

  1. 首先识别业务领域模型(?)
  2. 将每个用例,用户故事,业务需求与模型相关联
  3. 使用DDD的规定框架开发解决方案
  4. 或其他什么?

2 个答案:

答案 0 :(得分:4)

我通常在开始时做的是识别域的所有实体。

例如,让我们采用典型的博客方法。

我们可以拥有此实体,用户,帖子和管理员。

有时一开始就无法识别所有这些内容,所以我没有获得分析参与,而是首先接近代码。

因此,对我而言,下一个自然步骤是确定这些实体如何在它们之间进行协作。写帖子的用户是谁?然后让我们在代码中显示它:

$user->create(new Post($title, $body));

然后管理员可能需要查看帖子以接受它并在页面中显示:

$admin->reviewPostFrom($user);

如您所见,我们尽量使代码尽可能自然,这就是为了能够向域专家解释代码。

接下来是通过定义用例,我们可以创建应用程序所需的操作。

我们可以使用命令方法,例如:

class CreateNewPost
{
    protected $userId;
    protected $postTitle;
    protected $postBody;

    public function __construct(UserId $idUser, PostTitle $postTitle, PostBody $postBody)
    {
        // Here we can make some kind of validation of the data
    }
}

然后我们将命令发送到我们的命令总线,命令总线将负责处理此命令。它位于命令处理程序中,所有用例都发生在:

class CreateNewPostHandler
{
    // here we inject all dependencies we need to accomplish our use case
    public function __construct(UserRepositoryInterface $userRepo, etc..)
    {
        $this->userRepository = $userRepo;
        etc...
    }

    public function handle(CreateNewPost $command)
    {
        $user = $userRepo->getById($command->userId);
        $user->create(new Post($command->getTitle(), $command->getBody()));

        // Maybe we can launch an event here that launches a notification to admin, etc.
        $this->eventDispatcher(new PostCreatedEvent($user));
    }
}

正如您所看到的,我们在编码时并没有想到很多事情,我们意识到我们需要。我希望你感兴趣!!

答案 1 :(得分:1)

领域驱动设计鼓励增量开发,而不是瀑布式开发。 DDD是关于复杂领域的理解,它无法一次性完全发现。我建议经常重复你给出的步骤。

另一件事是用例和业务需求与域模型高度耦合。单独创建它们真的很难。