我是否违反了SOLID原则和n层微服务架构?

时间:2015-10-31 13:53:31

标签: c# domain-driven-design solid-principles n-layer

在以下示例中, AccountService ProductService 位于ASP.NET MVC应用中。 AccountWebAPI ProductWebAPI 是外部托管的 API微服务

1)我可以消除 ProductService 并协调检索 CustomerAccountController 本身的订单吗?这是因为我将Controller视为DDD(域驱动设计)中提到的 Application 层/服务。

2)我是否违反了n层体系结构,因为 ProductService 会调用同一层的 AccountService

3)由于 AccountWebAPI ProductWebAPI 微服务,因此必须将它们分隔为 AccountService 和客户端应用程序(MVC App)中的 ProductService 也是为了保持责任分离?因此, ProductService 需要重命名为 ProductAppService ,而 ProductService 只能与 ProductWebAPI 进行交互,例如 AccountService < / em>与 AccountWebAPI 进行对话。

public class CustomerAccountController : Controller 
{ 
    IProductService _productService;

    public CustomerAccountController(IProductService productService)
    {
        _productService = productService;
    }

    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Account(int customerId)
    {
        var orders = _productService.GetOrders(customerId);

        return View(orders);
    }
}

public class ProductService 
{ 
    IAccountService _accountService; 
    IProductWebAPI _productWebAPI;

    ProductService(IAccountService accountService, IProductWebAPI productWebAPI)
    {
        _accountService = accountService;
        _productWebAPI = productWebAPI;
    }

    IList<Order> GetOrders(int customerId)
    {
        // Find the International Customer Number for CustomerId
        object customer = _accountService.GetInternationCustomerInfo(customerId);

        // Convert the string type to int
        var modifiedCustomerNumber = Convert.ToInt32(customer.Id);

        // Get the orders
        return _productWebAPI.GetOrders(modifiedCustomerNumber);
    }
}

public class AccountService 
{ 
    IAccountWebService _accountWebAPI;

    CustomerService(IAccountWebService accountWebAPI)
    {
        _accountWebAPI = accountWebAPI;
    }

   object GetInternationCustomerInfo(int customerId) 
   { 
        return accountWebAPI.GetCustomer(customerId) 
   } 
}

更新:我意识到 OrderService 将是订单的相应服务名称,而不是 ProductService

The LAYERS:

查看 - 控制器 - 服务 - WebAPIs - DOMAIN - REPOSITORY

OrderView - CustomerAccountController - ProductService(在同一层中调用AccountService) - ProductWebAPI - ProductDomain - ProductRepository

2 个答案:

答案 0 :(得分:5)

名称AccountServiceProductService意味着您违反了Single Responsibility PrincipleOpen Closed PrincipleInterface Segregation Principle,这是{{3}的60% }。

SOLID principles解释了对此的推理,但简而言之:

  

违反了单一责任原则,因为每个类别的方法都没有高度凝聚力。与这些方法相关的唯一事实是它们属于同一个概念或实体。

     

设计违反了开放/封闭原则,因为几乎每次[方法]添加到系统时,都需要更改现有接口及其实现。每个接口至少有两个实现:一个实际实现和一个测试实现。

     

违反了接口隔离原则,因为接口[例如IProductService]很宽(有许多方法),并且这些接口的使用者被迫依赖于他们不使用的方法。

解决方案是为每个用例提供自己的类。详细解释了此设计this articlehere

我甚至会说具有相同结构的Web API控制器导致相同类型的SOLID违规。实际上,如果您应用文章给出的设计,您可以完全删除所有Web API控制器,并将其替换为能够传递消息的单个基础结构逻辑。这样的设计被描述为here(本文主要讨论WCF,但它也适用于Web API,Web API的工作示例可以在文章链接到的here中看到。) / p>

答案 1 :(得分:3)

  

1)我可以消除ProductService并协调在CustomerAccountController本身中检索订单吗?

你可以这样做,但这意味着你会将交付逻辑与应用逻辑混在一起。这不是最严重的SRP违规,但这将删除为同一用例添加第二个传递机制(除了Web API之外)的选项。在某些情况下,这可能是一种有效的权衡。

  

2)我是否违反了n层架构,因为ProductService调用的AccountService是同一层?

绝对不是。架构是一组受限制的技术决策。 违反架构的唯一方法是建立第二个并行架构,以某种方式打破原始架构的原则。在这里,您甚至不会违反n层方法,因为它中没有任何内容表示您不应该在同一层中呼叫某人。

  

3)由于AccountWebAPI和ProductWebAPI是微服务,它们是否必须在客户端应用程序(MVC App)中作为AccountService和ProductService分开,以保持责任分离?因此,ProductService需要重命名为ProductAppService,ProductService应该与ProductWebAPI交互,就像AccountService与AccountWebAPI的对话一样。

你的问题表明微服务的使用可能不是一个经过深思熟虑,受过教育的选择。微服务是将责任分离到极端。它们应该是可以独立部署的share as few things as possible。我还建议您首先为子域和有界上下文(大型业务区域)建模。微服务自然会落入其中一个BC。