应用服务 - 业务分布

Application Services - Distribution of Operations

我有以下代码:

代表客户的实体。

public class Customer
{
    public int CustomerId { get; set; }
    public string Name { get; set; }

    public int CountryId { get; set; }    
}

代表国家的实体:

public class Country
{
    public int CountryId { get; set; }
    public string Name { get; set; }
}

持有客户 CRUD 操作的服务..

public interface ICustomerService
{
    //Save..
    //Update..
    //Another domain specific operations...
}

要允许用户在 select 客户所在国家/地区进行注册,必须提供一项操作,即 returns 可用于 selection 的国家/地区列表。

我有以下选择:

我应该用什么? 为什么?

一切都是为了凝聚力。名字'ICustomerService'和'ICountryService'不代表商家的意图。在您的情况下,最好将其称为 'IRegistrationService',您可以在其中反映您的所有注册功能。在此 'RegistrationService' 中,您可以重复使用现有的存储库。但重要的是 'RegistrationService' 表示您的子域。

Put this operation within the ICustomerService, for example GetAvailableCountriesToCustomerRegister ().

这样做会破坏五分之三的 SOLID 原则,因为 (source):

The Single Responsibility Principle is violated, because the methods in each class are not highly cohesive. The only thing that relates those methods is the fact that they belong to the same concept or entity.

The design violates the Open/Closed Principle, because almost every time a query is added to the system, an existing interface and its implementations need to be changed. Every interface has at least two implementations: one real implementation and one test implementation.

The Interface Segregation Principle is violated, because the interfaces are wide (have many methods) and consumers of those interfaces are forced to depend on methods that they don’t use.

但是你的第二个选择也好不到哪儿去:

Create another service called ICountryService and put this operation in it, along with the CRUD operations.

这导致了完全相同的情况,仍然违反了所有三个 SOLID 原则。

此处的解决方案是为查询提供自己的抽象,并为每个查询提供自己的消息和实现,如 here 所述。