You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

整洁架构(Clean Architecture)技术问询:Presenter与Controller交互可能性及职责划分、实现细节疑问

关于整洁架构(Clean Architecture)的职责划分与实现细节解答

我来逐个拆解你提出的这三个关于Uncle Bob整洁架构的疑问,结合架构原则和实际场景给出我的理解:

1. Presenter与Controller的交互,以及Web场景下View的角色

首先明确:Presenter和Controller在整洁架构中是平行的接口适配器层组件,二者不直接交互,它们都依赖内层的用例层(Use Case层),但彼此之间没有依赖关系,各自职责清晰:

  • Controller的核心是接收外部输入(比如HTTP请求、用户事件),将输入转换为用例能理解的参数,然后触发用例执行;
  • Presenter的核心是接收用例的输出(通过用例的输出端口),将其转换为适合View展示的格式(比如ViewModel),再传递给View。

回到Web场景的疑问:

  • View不需要持有Controller实例,也不该成为“智能对象”。正确的流程是:用户与View交互(比如点击按钮)时,View只负责触发一个外部请求(比如HTTP POST/GET请求到对应的接口),由应用的路由层(或框架)将请求转发给对应的Controller。此时View依然是“哑对象”——它只做UI渲染和事件转发,不包含任何业务决策或流程逻辑。
  • 绝对不应该让Presenter调用Controller,这会打破职责边界:Presenter的职责是格式转换,而不是触发新的业务流程;同样,也不该把所有逻辑塞进Controller导致它过度依赖View,Controller只负责输入解析和用例触发,不处理UI相关的格式转换。

2. 用例成功后获取额外展示数据的逻辑位置

你的判断是对的:绝对不能把这个逻辑放在Use Case里,因为用例的职责是封装业务规则,不应该和UI展示需求绑定(比如CLI和Web场景的展示需求完全不同)。

最优的实现方式是放在Controller中,原因如下:

  • Controller的职责之一就是协调业务流程。当第一个用例执行成功后,Controller可以根据UI的展示需求,调用另一个负责获取额外数据的用例(注意:额外数据的获取也要通过用例,而不是直接操作数据库,保证业务逻辑都封装在内层);
  • Controller拿到两个用例的输出后,将它们一起传递给Presenter,由Presenter整合并转换为View需要的统一ViewModel;
  • 为什么不放在View或Presenter里?View不应该处理任何业务流程;Presenter只负责格式转换,不负责业务流程的协调,否则会让Presenter承担超出职责的工作,同时打破依赖方向(Presenter依赖用例层,但如果让Presenter调用Controller,就变成外层依赖外层,不符合整洁架构的依赖原则)。

3. Controller与Presenter的实例创建

按照整洁架构的原则,所有外层组件(包括Controller、Presenter)的实例都应该由应用的入口(比如main函数)创建,而不是由高层Controller创建低层组件。

具体来说:

  • main函数作为整个应用的“组装者”,负责创建所有用例层的实例,然后创建对应的Controller(将用例实例注入给Controller)、Presenter(将用例的输出端口实现注入给Presenter);
  • 这种方式符合依赖倒置原则:内层的用例层不依赖外层的Controller和Presenter,外层组件依赖内层的抽象接口;同时也保证了组件的解耦,每个组件的依赖都由外部注入,便于测试和替换。

内容的提问来源于stack exchange,提问作者rahul Kushwaha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 11:34:10