C# MVC模式实现。其组件之间的n-关系是什么

C# MVC模式实现。其组件之间的n-关系是什么,c#,model-view-controller,design-patterns,C#,Model View Controller,Design Patterns,我在一个C项目中工作,为了在UI的不同部分之间实现某种统一,我们正在尝试使用MVC模式。客户端是基于windows窗体的,我正在尝试创建一个简单的MVC模式实现 这比预期的更具挑战性,但我仍然对MVC模式有一些疑问。问题主要来自其组件之间的n-n关系:这是我所理解的,但我一点也不确定。也许有人能纠正我 模型:可以在不同视图之间共享。模型视图之间的1-n关系 视图:显示模型的状态。不同视图?之间只能共享一个控制器?。与模型的1-1关系,与控制器的1-1关系 控制器:处理视图上的用户操作并更新模型。

我在一个C项目中工作,为了在UI的不同部分之间实现某种统一,我们正在尝试使用MVC模式。客户端是基于windows窗体的,我正在尝试创建一个简单的MVC模式实现

这比预期的更具挑战性,但我仍然对MVC模式有一些疑问。问题主要来自其组件之间的n-n关系:这是我所理解的,但我一点也不确定。也许有人能纠正我

模型:可以在不同视图之间共享。模型视图之间的1-n关系 视图:显示模型的状态。不同视图?之间只能共享一个控制器?。与模型的1-1关系,与控制器的1-1关系 控制器:处理视图上的用户操作并更新模型。一个控制器可以在不同的视图之间共享,一个控制器只能与一个模型交互? 我不确定最后两个:

一个视图可以有多个控制器吗?或者一个视图可以与另一个视图共享控制器吗?还是仅仅是一对一的关系? 控制器可以处理多个视图吗?它可以与多个模型交互吗? 此外,我还利用这个问题问了另一个与MVC相关的问题。我已经利用事件和委托抑制了MVC不同成员之间的所有同步调用。最后一个调用仍然是同步的,实际上是最重要的:视图和控制器之间的调用仍然是同步的,因为我需要知道控制器是否能够处理用户的操作。这是非常糟糕的,因为这意味着我可以阻止UI线程,从而在控制器处理或执行某些工作时阻止客户端本身。我怎样才能避免这种情况?我可以使用回调,但我如何知道回调来自哪个事件

PS:我不能在这个阶段改变模式,所以请避免使用MVP或MVVC等类型的答案


谢谢

我已经在C语言中实现了MVC模式。我不太了解理论,也不知道它应该是什么,或者不应该是什么。我只是认为模式是基本的想法,然后,你可以根据自己的需要以多种不同的方式使用这个想法。我会告诉你我的实现,希望它能帮助你

**The Model**
你的描述很清楚,所以没什么好说的了。这里是我定义业务对象的地方。我利用这一层包含对象验证规则

除了处理用户操作和更新视图外,我还为每个控制器设置了一个。在提交工作单元中的更改之前,我检查视图中的对象是否通过了模型层中定义的验证

在我的例子中,一个控制器可以管理多个模型,我希望每个控制器中只有一个视图

像一个建议一样,我希望将我的框架用于不同的UI,因此我有一个控制器的抽象实现,然后我有针对不同接口的特定控制器实现WebForms、WinForms等等

在您的情况下,我们可以简单地称之为表单、UI。。。我喜欢使用选项卡组织桌面应用程序,就像它们是web应用程序一样。一个选项卡表示一个控制器,依此类推,一个视图和一个或多个模型

总之,就我而言:


你可能有点过度思考和形式化了

以下是我的看法:

模特:这才是真正的工作。 控制器:这是将输入发送到模型的东西,所以它可以工作。 视图:显示结果。 就这样。最简单的类比是控制台应用程序——应用程序是模型,STDIN是控制器,STDOUT是视图

扩展这个类比,许多GUI应用程序都是通过连接到STDIN/STDOUT而构建在命令行应用程序之上的。在这种情况下,向STDIN发送数据的东西是控制器,从STDOUT获取数据并放在窗口上的东西是视图,控制台应用程序仍然是模型

又是CS101,输入,处理,输出。对于GUI应用程序来说,这只是一个比较棘手的问题,因为输入和输出通常在同一个窗口上

很明显,你不需要一个控制台应用程序来实现这一点——分离甚至可以在一个进程中完成。发生的所有其他奇怪的接线只是使部件之间的关系正常工作所需的任何东西。但是布线并不是最重要的一点——最重要的一点是职责的分离和代码的逻辑组织

所以,一个视图是否必须映射到一个控制器,或者任何其他正交性问题都是次要的。事实上,你可能只需要做你的问题领域所需要的任何事情,但我反对过分热衷于代码的泛化——注意,不要把实际上不一样的东西混在一起。

模型、视图和协作 Controller是概念层,而不是单个对象,所以老实说,从多重性的角度考虑它们并没有多大意义。不过,我可以试着给你一个大概的答案

控制器返回单个操作的单个结果;结果可能是一个实际的视图,也可能是其他的。但是,控制器实际上与视图没有任何交互;它所做的只是在结果中提供一到两条信息:应该使用的视图的名称,以及用于填充的模型(可选)。实际创建和绑定视图取决于视图引擎,这与正常的智能客户端UI逻辑有很大的不同

控制器可以与模型的几个不同部分交互,或者在某些情况下根本不与模型交互;这方面的关系没有规则。在操作结果中,控制器必须返回模型的0或1个实例,但这可能不是真正的域模型,它可能是视图模型

视图通常只绑定到一个模型或视图模型,尽管在某些情况下,视图可能只是内容,因此不绑定到任何内容

因此,用一种非常粗俗的巫术式说法:

控制器:模型=0..*:0* 控制器:视图=0..*:0..1请求或0..*:0..*总体 视图:模型=0..*:0..1
这些都是ASP.NET MVC特有的。如果您正在设计自己的MVC实现,那么显然您可以选择任何您喜欢的方式来实现它。不过,在WinForms中实现MVC还是很幸运的;表单的行为根本不像视图,即使是MVP/MVVM这样的模式也是相当困难的,尽管不是不可能的,c.f.微软的CAB/SCSF,直到你转向WPF。

概念层是一个很好的表达方式,也是我试图获得的想法之一……很难在三个答案中选择,但你的答案对我来说更清楚。非常感谢您的澄清!
**The Controller**
**The Views**
n models - 1 controller
1 controller - 1 view
--
n models - 1 view