如何在MVC模式中实现类之间的通信?
本文关键字:之间 通信 实现 MVC 模式 | 更新日期: 2023-09-27 18:12:51
前言:这个问题不是关于ASP的。. NET MVC框架。
Edit:更清楚的是,应用程序是用c#编写的游戏,所以各种web框架都不适用。
我应该如何最好地连接类与事件时,使用MVC模式构建的东西?
我想写一些MVC代码,这样我就可以更多地了解设计模式。我理解为什么模式的这三个元素应该分开,但是我不确定如何实现将它们连接在一起。我是用c#写这篇文章的,我也是一个新手,它让我想到应该使用事件。我主要不确定如何正确地订阅/取消订阅事件,我需要进行完整性检查。
例如,我将发布视图/控制器类。在本例中,视图希望发送一个DataRequest事件,控制器希望订阅该事件,以便将其传递给模型。另一方面,控制器会在某个时刻引发一个datauupdate事件,视图应该订阅这个事件。我实现它们相互订阅的方式有意义吗?
////////////////////////////////////////////////////
public class UIScreenView
{
public event System.EventHandler<System.EventArgs> DataRequestedEvent;
//====================================
private void DataUpdatedEventHandler(object sender, System.EventArgs args);
//====================================
//====================================
public void Subscribe(UIScreenController controller)
{
controller.DataUpdatedEvent += DataUpdatedEventHandler;
controller.Subscribe(this);
}
//====================================
//====================================
public void UnSubscribe(UIScreenController controller)
{
controller.DataUpdatedEvent -= DataUpdatedEventHandler;
controller.UnSubscribe(this);
}
}
And the Controller:
public class UIScreenController
{
private UIScreenView view;
public event System.EventHandler<System.EventArgs> DataUpdatedEvent;
private void DataRequestedEventHandler(object sender, System.EventArgs args);
public void Init(UIScreenView v)
{
view = v;
if (view != null)
{
view.Subscribe(this);
}
}
~UIScreenController()
{
if (view)
{
view.UnSubscribe(this);
view = null;
}
}
public void Subscribe(UIScreenView view)
{
view.DataRequestedEvent += DataRequestedEventHandler;
}
public void UnSubscribe(UIScreenView view)
{
view.DataRequestedEvent -= DataRequestedEventHandler;
}
private void DataRequestedEventHandler(object sender, System.EventArgs args)
{
//request data from model
}
}
你所做的和试图做的是MVP模式,而不是MVC。简而言之,MVC模式用于请求-响应架构,而不是事件驱动。流程为:
- UI做请求
- 控制器接受请求
- 控制器处理请求(如访问模型等)
- 控制器发送响应到UI
如果你想在c#中实现它,我假设是winform,那么你的请求将在事件中处理。假设在你的游戏中,你选择了"加载游戏"菜单,随后需要显示保存的游戏数据。
下面的例子只是一个说明,所以期望应用非现实生活中的逻辑。控制器的格式为:
public class SaveDataController
{
public SaveData[] GetSaveData()
{
return Model.GetSaveData();
}
}
UI会是这样的:
public void LoadGameButton_Click(object sender, EventArgs e)
{
SaveDataController controller = new SaveDataController();
SaveData[] saveData = controller.GetSaveData();
SaveDataList.DataSource = saveData;
}
这个例子显示了对控制器的请求是在一个按钮点击事件中被发起的。
正如其他人已经说过的,MVC架构不适合非web应用程序(或事件驱动),因为它不处理事件方法。大多数UI逻辑将在事件中处理。
首先,您所描述的被称为模型-视图-表示器。到目前为止,我找到的最好的描述是Robert Martin的《c#中的敏捷原则、模式和实践》。
第二,你不需要MVP的事件。其思想是呈现者和视图相互引用,并且知道它们的接口,这样数据请求/更新就可以直接调用。
第三,对于没有经验的开发人员来说,该模式可能很麻烦。这样做的好处是可以用假视图替换视图,这样您就可以轻松地对演示器进行单元测试。但是,如果您从oop开始,那么将视图和演示器合并到一个类中的贫血方法可能会更简单。
你搞反了。MVC的一个主要教训(相对于WebForms)是,在web应用程序中没有任何"事件"。您所拥有的只是HTTP规范,它将客户机和服务器之间的事务定义为GET/POST(以及不太常见的PUT/DELETE)。在MVC中没有"按钮点击"这样的东西。相反,您有一个来自页面上表单的HTTP POST。
此外,每个HTTP请求都与之前的请求完全断开连接,并且没有真正的好方法来保持客户端和服务器之间的连接打开。服务器真正能做的就是接受请求,然后呈现适当的响应。所有试图模糊这种脱节现实的尝试都导致了更弱的web框架,而不是更好的web框架。
各种MVC框架主要做的是所谓的"模型绑定"。HTTP POST或GET不附带从类构造的"对象";它实际上只有POST或GET变量和标题之类的。MVC世界中的模型绑定器基本上采用这些简单的参数,并根据期望的类类型(通常在控制器中定义,或按约定定义)动态地从这些参数中构造对象。然后,控制器允许您基于这些对象执行代码操作,并最终以视图的形式发送回响应。
在这一点上,你应该选择1-2个流行的MVC框架并学习它们的范例,而不是用你自己的框架重新发明轮子。我碰巧在ASP工作。我喜欢。NET MVC,但是Ruby on Rails也很擅长。每种主流语言可能都有1-2个成熟、可靠的MVC框架,所以你应该从使用你熟悉的语言的框架开始。在你熟悉了现有的MVC框架之后,你可以开始考虑如何以不同的方式实现它,如果这是你最终想要的。