【问题标题】:Facade usage and naming立面使用和命名
【发布时间】:2026-01-17 23:20:02
【问题描述】:

我的程序中的许多业务逻辑服务需要访问一组通用的非业务逻辑服务,例如电子邮件、打印、消息传递(消息框和提示)和日志记录。我计划创建一个门面来封装 EmailService、PrintService、MessageService 和 LogService,这样每个业务逻辑服务只需要门面类的一个构造函数参数,而不是每个服务的四个参数。

所以不是

public BusinessLogicService(IEmailService emailService, IPrintService printService, IMessageService messageService, ILogService logService)
{
   this.EmailService = emailService;
   this.LogService = logService;
   this.MessageService = messageService;
   this.PrintService = printService;
}

我要这个

public BusinessLogicService(ISomeFacade facade)
{
   this.SomeFacade = facade;
}

我的问题是:

  1. 这是外观模式的正确用法吗?如果没有,我应该怎么做?

  2. 我假设拥有许多业务服务所需的标准服务集是很常见的,那么这种封装 EmailService、PrintingService、MessagingService、LoggingService 的外观是否有标准命名约定?以及将来可能需要的其他一些非业务逻辑服务?

【问题讨论】:

  • 看起来像 服务定位器反模式
  • 在你的情况下ISomeFacade 的定义是什么?

标签: c# architecture facade


【解决方案1】:

您描述的不是facade,而是service locator(有关该模式的讨论,请参阅Is ServiceLocator an anti-pattern?)。请注意,想出名称的麻烦是创建IKitchenSink 接口的好兆头。

作为门面,它必须以某种方式简化与服务的交互——也许有一个 ArchveMessage 调用将协调所有 4 个服务的工作。

构造函数参数的数量通常无关紧要*,因为无论如何都可能会使用依赖注入框架创建此类对象。使用 DI 框架还可以通过提供一种记录所有方法调用的开始/结束/错误情况的方法来处理大多数“记录”职责。


*) 大量注入的依赖说明类的职责太多,需要从这个角度来看待。

【讨论】: