在以下示例中, 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
答案 0 :(得分:5)
名称AccountService
和ProductService
意味着您违反了Single Responsibility Principle,Open Closed Principle和Interface Segregation Principle,这是{{3}的60% }。
SOLID principles解释了对此的推理,但简而言之:
违反了单一责任原则,因为每个类别的方法都没有高度凝聚力。与这些方法相关的唯一事实是它们属于同一个概念或实体。
设计违反了开放/封闭原则,因为几乎每次[方法]添加到系统时,都需要更改现有接口及其实现。每个接口至少有两个实现:一个实际实现和一个测试实现。
违反了接口隔离原则,因为接口[例如
IProductService
]很宽(有许多方法),并且这些接口的使用者被迫依赖于他们不使用的方法。
解决方案是为每个用例提供自己的类。详细解释了此设计this article和here。
我甚至会说具有相同结构的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。