实施DDD(红皮书):为什么他将协作者作为价值对象?

时间:2016-05-31 10:13:57

标签: domain-driven-design

我与Vaughn Vernon的红皮书有关。

在协作有界上下文中,他将作者,成员,参与者,创建者等作为值对象,其中字段与它们所绑定的实体内联存储。

假设你做一个有一个Creator的讨论,那么Creator(id,name,email)的字段将存储在同一个表中(tbl_discussions)。

论坛也是如此。 (见下面的架构)

DROP DATABASE IF EXISTS iddd_collaboration;
CREATE DATABASE iddd_collaboration;
USE iddd_collaboration;
SET FOREIGN_KEY_CHECKS=0;

CREATE TABLE `tbl_dispatcher_last_event` (
    `event_id` bigint(20) NOT NULL,
    PRIMARY KEY (`event_id`)
) ENGINE=InnoDB;

CREATE TABLE `tbl_es_event_store` (
    `event_id` bigint(20) NOT NULL auto_increment,
    `event_body` text NOT NULL,
    `event_type` varchar(250) NOT NULL,
    `stream_name` varchar(250) NOT NULL,
    `stream_version` int(11) NOT NULL,
    KEY (`stream_name`),
    UNIQUE KEY (`stream_name`, `stream_version`),
    PRIMARY KEY (`event_id`)
) ENGINE=InnoDB;

CREATE TABLE `tbl_vw_calendar` (
    `calendar_id` varchar(36) NOT NULL,
    `description` varchar(500),
    `name` varchar(100) NOT NULL,
    `owner_email_address` varchar(100) NOT NULL,
    `owner_identity` varchar(50) NOT NULL,
    `owner_name` varchar(200) NOT NULL,
    `tenant_id` varchar(36) NOT NULL,
    KEY `k_owner_identity` (`owner_identity`),
    KEY `k_tenant_id` (`name`,`tenant_id`),
    PRIMARY KEY (`calendar_id`)
) ENGINE=InnoDB;

CREATE TABLE `tbl_vw_calendar_entry` (
    `calendar_entry_id` varchar(36) NOT NULL,
    `alarm_alarm_units` int(11) NOT NULL,
    `alarm_alarm_units_type` varchar(10) NOT NULL,
    `calendar_id` varchar(36) NOT NULL,
    `description` varchar(500),
    `location` varchar(100),
    `owner_email_address` varchar(100) NOT NULL,
    `owner_identity` varchar(50) NOT NULL,
    `owner_name` varchar(200) NOT NULL,
    `repetition_ends` datetime NOT NULL,
    `repetition_type` varchar(20) NOT NULL,
    `tenant_id` varchar(36) NOT NULL,
    `time_span_begins` datetime NOT NULL,
    `time_span_ends` datetime NOT NULL,
    KEY `k_calendar_id` (`calendar_id`),
    KEY `k_owner_identity` (`owner_identity`),
    KEY `k_repetition_ends` (`repetition_ends`),
    KEY `k_tenant_id` (`tenant_id`),
    KEY `k_time_span_begins` (`time_span_begins`),
    KEY `k_time_span_ends` (`time_span_ends`),
    PRIMARY KEY (`calendar_entry_id`)
) ENGINE=InnoDB;

CREATE TABLE `tbl_vw_calendar_entry_invitee` (
    `id` int(11) NOT NULL auto_increment,
    `calendar_entry_id` varchar(36) NOT NULL,
    `participant_email_address` varchar(100) NOT NULL,
    `participant_identity` varchar(50) NOT NULL,
    `participant_name` varchar(200) NOT NULL,
    `tenant_id` varchar(36) NOT NULL,
    KEY `k_calendar_entry_id` (`calendar_entry_id`),
    KEY `k_participant_identity` (`participant_identity`),
    KEY `k_tenant_id` (`tenant_id`),
    PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `tbl_vw_calendar_sharer` (
    `id` int(11) NOT NULL auto_increment,
    `calendar_id` varchar(36) NOT NULL,
    `participant_email_address` varchar(100) NOT NULL,
    `participant_identity` varchar(50) NOT NULL,
    `participant_name` varchar(200) NOT NULL,
    `tenant_id` varchar(36) NOT NULL,
    KEY `k_calendar_id` (`calendar_id`),
    KEY `k_participant_identity` (`participant_identity`),
    KEY `k_tenant_id` (`tenant_id`),
    PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `tbl_vw_discussion` (
    `discussion_id` varchar(36) NOT NULL,
    `author_email_address` varchar(100) NOT NULL,
    `author_identity` varchar(50) NOT NULL,
    `author_name` varchar(200) NOT NULL,
    `closed` tinyint(1) NOT NULL,
    `exclusive_owner` varchar(100),
    `forum_id` varchar(36) NOT NULL,
    `subject` varchar(100) NOT NULL,
    `tenant_id` varchar(36) NOT NULL,
    KEY `k_author_identity` (`author_identity`),
    KEY `k_forum_id` (`forum_id`),
    KEY `k_tenant_id` (`tenant_id`),
    KEY `k_exclusive_owner` (`exclusive_owner`),
    PRIMARY KEY (`discussion_id`)
) ENGINE=InnoDB;

CREATE TABLE `tbl_vw_forum` (
    `forum_id` varchar(36) NOT NULL,
    `closed` tinyint(1) NOT NULL,
    `creator_email_address` varchar(100) NOT NULL,
    `creator_identity` varchar(50) NOT NULL,
    `creator_name` varchar(200) NOT NULL,
    `description` varchar(500) NOT NULL,
    `exclusive_owner` varchar(100),
    `moderator_email_address` varchar(100) NOT NULL,
    `moderator_identity` varchar(50) NOT NULL,
    `moderator_name` varchar(200) NOT NULL,
    `subject` varchar(100) NOT NULL,
    `tenant_id` varchar(36) NOT NULL,
    KEY `k_creator_identity` (`creator_identity`),
    KEY `k_tenant_id` (`tenant_id`),
    KEY `k_exclusive_owner` (`exclusive_owner`),
    PRIMARY KEY (`forum_id`)
) ENGINE=InnoDB;

CREATE TABLE `tbl_vw_post` (
    `post_id` varchar(36) NOT NULL,
    `author_email_address` varchar(100) NOT NULL,
    `author_identity` varchar(50) NOT NULL,
    `author_name` varchar(200) NOT NULL,
    `body_text` text NOT NULL,
    `changed_on` datetime NOT NULL,
    `created_on` datetime NOT NULL,
    `discussion_id` varchar(36) NOT NULL,
    `forum_id` varchar(36) NOT NULL,
    `reply_to_post_id` varchar(36),
    `subject` varchar(100) NOT NULL,
    `tenant_id` varchar(36) NOT NULL,
    KEY `k_author_identity` (`author_identity`),
    KEY `k_discussion_id` (`discussion_id`),
    KEY `k_forum_id` (`forum_id`),
    KEY `k_reply_to_post_id` (`reply_to_post_id`),
    KEY `k_tenant_id` (`tenant_id`),
    PRIMARY KEY (`post_id`)
) ENGINE=InnoDB;

现在,如果用户更改了他的电子邮件,那么您必须更新/同步所有表以反映更改。

我只是想知道他为什么想出那个解决方案?他考虑的是什么?

还有其他选择吗?就像实现相同的代码一样,但以不同的方式坚持下去?

1 个答案:

答案 0 :(得分:6)

从书中可以看出:

  

没有努力保留Collborator值实例   与身份和访问上下文同步。他们是不变的   并且只能完全替换,不能修改。 p.468 para。 1

这意味着当值被替换时,基本上会发生同步。

  

如果标识中的Collaborator名称或电子邮件地址发生更改   和访问上下文,此类更改不会自动更新   协作上下文。这种变化很少发生,所以   团队决定保持这个特殊的设计简单   不要尝试使用对象对远程Context中的更改进行sycnrhonize   在他们的本地语境中。 p.469 para。 1

您还需要宣读 p.476 para.2 Can You Handle the Responsibility 。在本节中,Vaughn演示了在必须处理乱序消息消耗时保持数据在有界上下文之间同步的复杂程度。还概述了为了保证消息的顺序,我们可能不依赖于复杂的消息传递基础结构,而只是从远程上下文中提取消息(例如,通过RESTful通知服务 2 )。

这总是一个权衡问题以及您的域名可以接受的内容。

<子> 2。这种方法在第312秒描述。将通知发布为RESTful资源。