编辑:更清楚的是,应用程序是用C#编写的游戏,因此各种Web框架都不适用。
在使用MVC模式构建内容时,如何最好地将类与事件连接起来?
我想写一些MVC代码,以便我可以更多地了解设计模式。我理解为什么模式的这三个元素中的每一个都应该是分开的,但我不确定如何实现将它们连接在一起。我在C#中写这个,我也是新手,我觉得应该使用事件。我主要不确定如何正确订阅/取消订阅活动,我需要进行健全性检查。
例如,我将发布视图/控制器类。在此示例中,View希望发送DataRequest事件,并且Controller希望订阅该事件以便将其传递给Model。另一方面,Controller会在某个时候引发View应该订阅的DataUpdated事件。我实现他们如何相互订阅的方式是否有意义?
////////////////////////////////////////////////////
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);
}
}
和控制器:
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
}
}
答案 0 :(得分:2)
首先,您所描述的内容称为Model-View-Presenter。到目前为止,我发现的最好的描述是罗伯特·马丁的“敏捷原则,模式和实践在c#”。
其次,您不需要MVP事件。我们的想法是,演示者和视图相互引用并了解其接口,以便直接调用数据请求/更新。
第三,对于没有经验的开发者来说,这种模式可能很麻烦。好处是视图可以用假视图替换,因此您可以轻松地对演示者进行单元测试。但是,如果这是oop的开始,那么将视图和演示者合并到一个类中的贫血方法可能会更简单。
答案 1 :(得分:2)
你做过和尝试过的是MVP模式,而不是MVC。简而言之,MVC模式用于请求 - 响应架构而不是事件驱动。流程是:
如果你想在C#中实现它,我假设winform,那么你的请求将在事件内处理。让我们在你的游戏中说你选择菜单加载游戏,之后需要显示已保存的游戏数据。
以下示例只是一个例子,因此期望应用非现实生活逻辑。控制器将如下:
public class SaveDataController
{
public SaveData[] GetSaveData()
{
return Model.GetSaveData();
}
}
用户界面就像:
public void LoadGameButton_Click(object sender, EventArgs e)
{
SaveDataController controller = new SaveDataController();
SaveData[] saveData = controller.GetSaveData();
SaveDataList.DataSource = saveData;
}
此示例显示正在按钮单击事件中启动对控制器的请求。
正如其他人已经说过的那样,MVC架构不适合非Web应用程序(或事件驱动),因为它不处理事件方法。大多数UI逻辑都将在事件中处理。
答案 2 :(得分:1)
你有点倒退了。 MVC的主要教训之一(与WebForms类似)是 Web应用程序中没有任何“事件”。您所拥有的只是HTTP规范,它将客户端和服务器之间的事务定义为GET / POST(不太常见,PUT / DELETE)。在MVC中没有“按钮点击”这样的东西。相反,您有来自页面上的表单的HTTP POST。
此外,每个HTTP请求都与之前的HTTP请求完全断开,并且在客户端和服务器之间保持连接打开并不是一个好方法。所有服务器实际上都可以接受请求,然后呈现适当的响应。所有试图混淆这种不连贯的现实的尝试都导致了较弱的网络框架,而不是更好的框架。
各种MVC框架主要执行所谓的“模型绑定”。 HTTP POST或GET不带有从类构造的“对象”;所有它真的有POST或GET变量和标题等。 MVC世界的模型绑定器基本上采用这些简单的参数,并根据预期的类类型(通常在控制器中定义,或按惯例)在运行中构建对象。然后,Controller允许您基于这些对象执行代码操作,并最终以View的形式发送回响应。
此时,您应该选择1-2个流行的MVC框架并学习他们的范例,而不是用自己的框架重新发明轮子。我碰巧在ASP.NET MVC中工作并喜欢它,但Ruby on Rails非常好。对于每种主要语言,可能有1-2个成熟,可靠的MVC框架,因此您应该从使用您熟悉的语言开始。
在熟悉现有的MVC框架之后,您就可以开始思考如何以不同的方式实现它,如果这是最终的结果。