【问题标题】:Role of services in domain driven design服务在领域驱动设计中的作用
【发布时间】:2017-01-27 06:45:39
【问题描述】:

我最近发现域驱动设计 (DDD) 是某些应用程序的更好选择(即涉及复杂业务逻辑的应用程序,而不是通过 UI 公开的简单 CRUD 操作)。

我浏览了以下有关领域驱动设计 (DDD) 的网站。

https://www.infoq.com/articles/ddd-in-practice

Domain Driven Design: Domain Service, Application Service

我无法得出结论/理解的是以下几点:

(1) 服务在领域驱动设计 (DDD) 中的作用是什么?您能用一个示例服务、域对象、DAO(使用 Java)来解释吗?

(2) 如果我需要使用 Java 创建域/业务对象,那么要遵循的命名约定是什么?是不是像 CustomerBO、ProductBO 等?

您能帮我举一些简单的 Java 示例吗?

我不喜欢下面给出的示例(在答案中),因为域对象除了携带数据之外没有做任何事情,这仍然是一个贫血模型。任何人都可以通过在域对象中进行一些行为来帮助我举一个明确的例子吗?

【问题讨论】:

  • 我不喜欢下面给出的示例,因为域对象除了携带数据之外没有做任何事情,这是一个贫血模型。谁能帮我举一个明确的例子?

标签: java domain-driven-design anemic-domain-model


【解决方案1】:

这是一个加载的问题,但我会尝试在某种程度上回答它。 我强烈建议您查看 Vaughn Vernon 的 github sample。他是Implementing Domain Driven Design的作者。

在您提供的 SO 链接中,服务的定义非常好。因此,我将只为您提供示例代码来消化该描述。

以在身份访问域中配置租户为例。

这里有一些来自 Vaughn 的 github 的非常清晰的示例:

这里是租户域对象

package com.saasovation.identityaccess.domain.model.identity;

    public class Tenant extends extends ConcurrencySafeEntit {
        public Tenant(TenantId aTenantId, String aName, String aDescription, boolean anActive) {
         ...   
        }
        public Role provisionRole(String aName, String aDescription) {
          ...
        }
        public void activate(){}
        public void deactivate(){}
        ....

    }

租户存储库

package com.saasovation.identityaccess.domain.model.identity;

public interface TenantRepository {

    public void add(Tenant aTenant);
}

租户域服务

package com.saasovation.identityaccess.domain.model.identity;

public class TenantProvisioningService {

    private TenantRepository tenantRepository;

    public Tenant provisionTenant(
            String aTenantName,
            String aTenantDescription,
            FullName anAdministorName,
            EmailAddress anEmailAddress,
            PostalAddress aPostalAddress,
            Telephone aPrimaryTelephone,
            Telephone aSecondaryTelephone) {

            Tenant tenant = new Tenant(
                        this.tenantRepository().nextIdentity(),
                        aTenantName,
                        aTenantDescription,
                        true); // must be active to register admin

            this.tenantRepository().add(tenant);

    }

}

这是一个应用服务

package com.saasovation.identityaccess.application;

@Transactional
public class IdentityApplicationService {

    @Autowired
    private TenantProvisioningService tenantProvisioningService;


    @Transactional
    public Tenant provisionTenant(ProvisionTenantCommand aCommand) {

        return
            this.tenantProvisioningService().provisionTenant(
                        aCommand.getTenantName(),
                        aCommand.getTenantDescription(),
                        new FullName(
                                aCommand.getAdministorFirstName(),
                                aCommand.getAdministorLastName()),
                        new EmailAddress(aCommand.getEmailAddress()),
                        new PostalAddress(
                                aCommand.getAddressStateProvince(),
                                aCommand.getAddressCity(),
                                aCommand.getAddressStateProvince(),
                                aCommand.getAddressPostalCode(),
                                aCommand.getAddressCountryCode()),
                        new Telephone(aCommand.getPrimaryTelephone()),
                        new Telephone(aCommand.getSecondaryTelephone()));
    }
}

【讨论】:

  • 这个例子我没看懂,为什么我们有2个服务?
  • 应用程序服务将是外部消费者将用于对该域进行操作的服务。另一方面,域服务在您的域内部,仅处理您的域对象或存储库无法处理的逻辑。如果您查看 github 中的完整示例,它会给您一个更好的主意。这些只是完整类的 sn-ps。
  • 抱歉延迟响应,域对象在这里的作用是什么?除了携带数据,它什么也没做,这是一个贫血模型。
  • @developer 去浏览整个 git 存储库。这不会花费你太多时间,但你会学到很多东西。正如我所说,我只粘贴了每节课的一部分。 Tenant 域对象上有很多方法/行为,所以它不是贫血的。activate()offerRegistrationInvitation(String aDescription)provisionRole(...) 只是几个例子。看看here.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-25
相关资源
最近更新 更多