我是一名Web开发人员,但我对C ++和C#非常了解。但是,最近我编写了一个GUI应用程序,我开始迷失在如何处理我的控制器和视图逻辑之间的关系。在PHP中它非常简单 - 我可以闭着眼睛编写自己的MVC模式 - 主要是因为PHP是无状态的,并且每个请求都会重新生成整个表单。但是在应用程序编程语言中,我很快就迷失了。
我的问题是:如何将我的控制器与视图分开?视图是否应附加到控制器的事件 - 或视图是否应实现控制器与之交互的接口?
答案 0 :(得分:6)
如果我是你,我会从您视图的界面中公开事件。这将允许您使控制器成为整个交互的中心。
控制器将首先加载并实例化视图,我将使用依赖注入,这样您就不会在视图本身上创建依赖关系,而只是在接口上创建依赖关系。 控制器将访问模型并将数据加载到视图中。 控制器将绑定到视图接口上定义的事件。 然后,控制器将通过事件处理将数据保存回模型。
如果您愿意,也可以使用事件代理,这将无需为每个视图声明一个接口。这样您就可以通过属性绑定到事件。
这会使Controller依赖于模型和视图接口,视图仅依赖于数据,而且模型没有依赖关系。
上述设计思路的一些示例可以在CAB和Smart Client Software Factory Link To Smart Client中找到。他们使用MVP模式,但同样可以轻松应用于MVC模式。
答案 1 :(得分:3)
大多数GUI框架(从MFC到SWT再到其他)都已经基于MVC了。事实上,MVC模式最初是由Smalltalk-80创建的,后来首先真正用于GUI开发。
仔细检查并查看所选GUI工具包的标准和建议做法。有时,在解决某个问题或使用特定工具包时,MVC不是一个好的模式。
请记住:MVC是一个很好的模式,但不是一个适合所有解决方案,不要尝试在基于事件或功能样式编程的情况下将问题强加到MVC中。
答案 2 :(得分:1)
想象一下这个GUI:
Zergling单位作为外星人图标呈现给用户。你可以看到它处于空闲动画状态。将此称为视图。
玩家通过单击它和目标位置来移动单位。如果需要,您可以为播放器替换AI。将此称为控制器。
单位在战斗中,每个游戏框架计算单位的HP和攻击范围。您可以更改此数据以使Zergling成为范围单位。称之为模型。
记住这个比喻并为MVC设计扩展它。
答案 3 :(得分:1)
您要记住的重要一点是,在您的MVC设置中,Controller必须知道要调用哪个View,但View必须知道Controller。
因此,您的View必须为控制器提供与其交互的通用方式,以便您可以让多个不同的控制器调用相同的View(例如,作为参数提供的某些数据的标准化图形输出)。
这为您提供了灵活性:
如果您将View与特定控制器分离,并且从控制器中了解要调用哪个View,那么您就可以了。
答案 4 :(得分:0)
您的控制器应该明确绑定到视图实现的接口上定义的事件。
你如何做到这一点可能是棘手的部分。依赖注入?一个观点工厂?让视图实例化它想要的控制器吗?这实际上取决于应用程序的复杂程度。
对于一些非常快速和简单的东西,我首先要让每个视图构建它的控制器,然后看看其他选项是否需要变大。就个人而言,我认为一个完整的依赖注入框架对于六种形式来说是过度的:]