MVC 中View 和Controller 之间的关系真的只是一个Strategy 模式吗?

Is the relationship between a View and a Controller in MVC really just a Strategy pattern?

《四人帮》书中陈述如下:

[...] The main relationships in MVC are given by the Observer, Composite and Strategy design patterns.

我能找到的最佳示例是 this github 存储库,它显示了以下 class 图:

我对 MVC 的策略部分特别感兴趣,其中包含以下内容:

MVC Name GoF Name
View Context
Controller Strategy
ConcreteController ConcreteStrategy

关于View和Controller的关系,Head First Design Patterns一书是这样说的:

The controller may also ask the view to change. When the controller receives an action from the view, it may need to tell the view to change as a result. For example, the controller could enable or disable certain buttons or menu items in the interface

它还显示了一个示例,其中 ConcreteController 等价物 BeatController) 定义了与 ConcreteView 等价物 (DJView) 的附加关联:

package headfirst.designpatterns.combined.djview;
  
public class BeatController implements ControllerInterface {
    BeatModelInterface model;
    DJView view;
   
    // BeatController implementation
}

此关联不存在于策略模式中,它只有一个从 ContextStrategy 的箭头(而不是相反)。此外,我在网上看到了一些例子,这些例子也定义了从控制器到视图的关联:

Controller和View的关系真的只是一种策略吗?如果不是那是什么?

解决您问题的一部分:策略模式中 ContextStrategy 之间的关系。您在书籍等中看到的 UML 图只是一个 示例 实现,这通常只显示 ContextStrategy 中的 link。然而 Strategy 必须知道一些关于它的 Context 才能完成它的工作,这通常作为参数传递给 Strategy 对象的方法调用。当有许多参数要传递时,可以通过将对 Context 对象的引用传递给 Strategy 构造函数来替换它们。这个决定是 'tailoring a pattern to fit its context'.

的一个例子

是的,这真的只是一种策略。 ContextStrategy 之间的关系可能很复杂,GoF 书中有几个地方提到了它。

Strategy and Context interact to implement the chosen algorithm. A context may pass all data required by the algorithm to the strategy when the algorithm is called. Alternatively, the context can pass itself as an argument to Strategy operations. That lets the strategy call back on the context as required. --page 317

如此处所示,从 StrategyContext 的依赖项是可选的。在 GoF 书中,为了简单起见,UML 图通常会省略可选关系。请注意,在 Strategy 知道其 Context 的情况下,依赖项将依赖于抽象而不是 ConcreteContext。具体 类 之间的循环依赖通常不是一个好主意。

设计 ContextStrategy 之间的关系需要一些思考。

The Strategy and Context interfaces must give a ConcreteStrategy efficient access to any data it needs from a context, and vice versa.

One approach is to have Context pass data in parameters to Strategy operations—in other words, take the data to the strategy. This keeps Strategy and Context decoupled. On the other hand, Context might pass data the Strategy doesn't need.

Another technique has a context pass itself as an argument, and the strategy requests data from the context explicitly. Alternatively, the strategy can store a reference to its context, eliminating the need to pass anything at all. Either way, the strategy can request exactly what it needs. But now Context must define a more elaborate interface to its data, which couples Strategy and Context more closely.

The needs of the particular algorithm and its data requirements will determine the best technique. --page 319