【发布时间】:2016-06-14 09:13:02
【问题描述】:
我的问题很简单。今天,有很多实现MVC(Model-View-Control)架构的前端和后端框架。
“MVC 中的控制器”是外观设计模式的示例吗?
【问题讨论】:
标签: design-patterns model-view-controller controller object-oriented-analysis facade
我的问题很简单。今天,有很多实现MVC(Model-View-Control)架构的前端和后端框架。
“MVC 中的控制器”是外观设计模式的示例吗?
【问题讨论】:
标签: design-patterns model-view-controller controller object-oriented-analysis facade
好的,首先让我这样说:我认为术语“MVC”或“Facade”的定义不够好,不足以使这个问题成为一个简洁而绝对可以回答的问题。 MVC 有许多不同的“风格”,每一种都有不同的属性。所以说清楚“是”或“否”我觉得有点自以为是,但也没那么有用。
我不相信 Facade 和 Controller 是一回事。
如果您查看四组设计模式,我们不能仅通过代码结构来确定模式的含义或实现。这意味着,您不能查看大多数代码并说“这显然是 X 模式”。
Facade 和 Adapter 就是一个简单的例子。从代码的角度来看,两者是相同的,所以区别不在于技术,而在于你如何使用它。您构建一个适配器以使用定义的 API(接口)将一个复杂系统连接到另一个复杂系统。当您为相同目的创建新界面时,您会构建外观。这意味着区别在于新建层是满足现有接口(适配器)还是创建新接口(外观)。写完就没什么区别了。
我们可以对 Decorator 和 Proxy 说同样的话。事实上,我们可以为很多人做到这一点。我在演讲的前半部分Beyond Design Patterns基于这个Blog Post by the same name讲了这个事实。
最终,我们需要看看你为什么要编写代码,看看控制器和外观是否是同一事物(或相似)。
为什么要编写外观:因为您希望提供对复杂系统的更简单访问,通常用于特定用例。来自 Sourcemaking:
为子系统中的一组接口提供统一的接口。 Facade 定义了一个更高级别的接口,使子系统更易于使用。
为什么要编写控制器:因为您想为“外部用户”提供特定的功能。控制器将请求路由到您的“模型”并与视图交互。
什么是相同的(将简单的界面路由到幕后更复杂的集合)。应用程序中的控制器与 Facade 的作用类似,因为它充当特定用例的更复杂应用程序的“网关”。
我认为这个问题真的很有趣,因为它让我们思考的原因远远多于是什么。如果您将控制器视为可以从多个位置调用的通用抽象(在一种情况下从 HTTP,在另一种情况下从 CLI),那么它确实开始看起来像 Facade 的 LOT。
但是,如果您的控制器倾向于在单一上下文中使用,那么它们将不再看起来像 Facades,而是开始看起来像一般代码。
这里的细微差别非常重要。事实上,对我来说,简单地提出问题并思考细微差别远比任何答案都重要。
【讨论】:
正如@ircmaxell 指出的那样,回答一个定义不明确的问题会很麻烦。
为了清楚起见,我将使用Fowler's definition of an MVC Controller(强调我的):
MVC 的表示部分由剩下的两个元素组成:视图和控制器。 控制器的工作是接受用户的输入并弄清楚如何处理它。
在这一点上,我要强调的是,不仅仅是一个视图和 控制器,对于屏幕的每个元素,每个控件,您都有一个视图-控制器对和整个屏幕。
我将使用关于 Facade 的 intent 的文本(来自我的 GoF 副本):
意图
为子系统中的一组接口提供统一的接口。 Facade 定义了一个更高级别的接口,使子系统更易于使用。
根据这些定义,它们不是一回事。
现在,值得一提的是,GRASP Controller(它不是 MVC)通常是应用程序或域层的外观:
名称:控制器 问题:UI 层之外的第一个对象接收和协调(“控制”)系统操作? 解决方案:将责任分配给代表以下选择之一的对象:
- 表示整个“系统”、“根对象”、软件在其中运行的设备或主要子系统(这些都是外观控制器的变体)。
- 表示发生系统操作的用例场景(用例或会话控制器)
【讨论】: