对于我来说,一个好的MVC实现的试金石是交换视图是多么容易。由于懒惰,我总是做得非常糟糕,但现在我想做得对。这是在C ++中,但它应该同样适用于非桌面应用程序,如果我相信炒作。
以下是一个示例:应用程序控制器必须在后台检查某些URL是否存在。它可以连接到“URL available”事件(使用Boost Signals),如下所示:
BackgroundUrlCheckerThread(Controller & controller)
{
// ...
signalUrlAvailable.connect(
boost::bind(&Controller::urlAvailable,&controller,_1))
}
那么Controller::urlAvailable
是什么样的?
这是一种可能性:
void
Controller::urlAvailable(Url url)
{
if(!view->askUser("URL available, wanna download it?"))
return;
else
// Download the url in a new thread, repeat
}
对我来说,这看起来像是视图和控制器的粗略耦合。这种耦合使得在使用网络时无法实现视图(除了协程之外)。
另一种可能性:
void
Controller::urlAvailable(Url url)
{
urlAvailableSignal(url); // Now, any view interested can do what it wants
}
我偏爱后者,但似乎如果我这样做会有:
那么你有什么建议去除耦合并降低复杂性?提前谢谢。
答案 0 :(得分:3)
对于我来说,一个好的MVC实现的试金石是交换视图是多么容易。
我可能会说这个,但我不同意这个说法。这在纸面上看起来不错,但现实世界的例子表明,良好的用户界面具有响应性和交互性,这通常需要将视图和控制器交织在一起。尝试编写一个完全通用的控制器来处理无法预料的理论视图会给控制器和视图增加大量的代码和复杂性。相互关联的视图/控制器在我的经验中运作得更好 - 我认为它是“M(VC)”。
我想说一个好的MVC实现的石蕊测试是你可以轻松地“添加”另一个视图/控制器对到模型。从一个视图/控制器(例如桌面操作员)对模型的更改是否传播到另一个视图/控制器(例如,Web远程用户)。该模型是否足够通用以支持不同的视图/控制器范例(例如桌面GUI,命令行,计划/批量输入,基于Web的UI,Web服务等)?
这并不是说控制器代码不能共享(例如从公共基础派生),但你必须在控制器应该处理的内容之间找到正确的界限(模型的外部操作)什么应该被认为是模型行为的一部分(模型的内部过渡)。视图代码同上。
我认为阅读"What goes into the “Controller” in “MVC”下的一些答案也会对此有所帮助。
答案 1 :(得分:0)
你让他们使用'm'解耦 - 模型和使用(在概念上)命令喜欢的模式和监听器模式来降低复杂性。
所以你的控制器看起来像这样:
void
Controller::urlAvailable(Url url)
{
Controller::fireSignal("urlAvailable", url, ... other possible parameter);
}
Controller::fireSignal(char* cmd, Url url, ... other possible parameters) {
Model &M = new Model();
M->command = cmd;
M->url = url;
M-> ... other possible
for(int v = Controller::ViewCount; --v >= 0; )
Controller::Views[v]->notice(M);
}
注意:我不是C ++程序员,请原谅我错误的语法。
MVC的整个想法是使用M(odel)将C(ontrol)与V(iew)解耦。这个例子极其简化。更实际的是对不同类型的相似信号使用不同的模型。
希望这有帮助。