直接从 class 更新模型中的数据
Updating Data in your model directly from a class
我正在制作一个简单的游戏作为基于随机事件的练习项目,以便更轻松地添加新事件我决定使用关键字系统,其中每个事件都分配给它们然后使用的关键字要处理事件,这可以像显示消息一样简单,更改模型中的数据或再次随机滚动 table。
我有一个 class 随机决定一个事件和 return 一个带关键字的字符串列表。
我想制作一个 class,其中所有关键字都存储为方法,然后可以使用列表调用这些方法。
像这样:
class Keyword
{
public void InputKeywords(List<string> Ikeywords)
{
foreach (var item in Ikeywords)
{
switch (item)
{
case "keyword0":
keyword0();
break;
case "keyword1":
keyword0();
break;
case "keyword2":
keyword0();
break;
}
}
}
private void keyword0()
{
//do something
}
private void keyword1()
{
//do something
}
private void keyword2()
{
//do something
}
}
现在我面临的问题是从关键字 class 更新模型中的数据。
因为事件是随机选择的,所以我不知道每个事件发送什么数据到 class 让它更新它。
我自己想出的解决方案:
- 使我的模型静态,访问数据不再有问题,Google 告诉我这是不受欢迎的,应该避免。
- 将模型发送到关键字 class,做一些魔术,然后 return 模型。将是一个简单的解决方案,但对我来说感觉不对,从我对 MVVM 的理解来看,应该从视图模型更新数据,但我可能想得太多了。
- 收集所有可能要更改的数据到单独的 class,将其发送到关键字 class,然后更新模型。这听起来很麻烦,感觉就像我只是把问题转移到别处。
我觉得我缺少执行此操作的“正确”方法。 “最佳”方法是什么?
首先,关键字 class 的命名在这里让人感到误导。它基本上是一个事件处理程序,所以我也将其命名为 on(例如 RandomEventGenerator)
对于你的问题,我也不建议你使用静态模型。你的可测试性会受到影响,因为你不会在那里使用依赖注入。话虽如此,您的第二种方法似乎朝着正确的方向发展。我建议使用注入一个 EventInvoker 接口。
public interface IEventInvoker
{
public void RaiseEvent();
}
这可以在操作员中实现,它可以访问您的数据模型并具有预定义的操作来修改您的数据。
public class WeatherOperator : IEventInvoker
{
private readonly WeatherEngine _weatherEngine;
public WeatherOperator(WeatherEngine weatherEngine)
{
_weatherEngine = weatherEngine;
}
public void RaiseEvent()
{
StartSunshine();
}
public void StartSunshine()
{
_weatherEngine.RemoveClouds();
_weatherEngine.SetSunPosition(DayTimes.Noon);
}
public void LetItRain()
{
_weatherEngine.SetCloudes(CloudModes.FullCover);
_weatherEngine.SetRain(RainIntesity.Medium);
}
}
有了 IEventInvoker 的列表,您就可以转到您的 EventHandler。
public class RandomEventGenerator
{
private readonly List<IEventInvoker> _eventInvoker;
private readonly Dictionary<string, Action> _eventDictionary;
public RandomEventGenerator(List<IEventInvoker> eventOperator, List<string> keywords)
{
_eventInvoker = eventOperator;
_eventDictionary = RegisterKeywordsToRandomEvents(keywords);
}
private Dictionary<string,Action> RegisterKeywordsToRandomEvents(List<string> keywords)
{
var eventDictionary = new Dictionary<string, Action>();
foreach (var keyword in keywords)
{
var random = new Random();
var index = random.Next(_eventInvoker.Count);
eventDictionary.Add(keyword,_eventInvoker[index].RaiseEvent);
}
return eventDictionary;
}
public void EventByKeyword(string Keyword)
{
_eventDictionary[Keyword].Invoke();
}
public void RandomEvent()
{
var random = new Random();
var index = random.Next(_eventInvoker.Count);
_eventInvoker[index].RaiseEvent();
}
}
请注意,为了保持小,我没有在此处使用 null 检查或输入验证,这是强烈推荐的。
使用这种方法,您的 model/data 和视图 model/data 访问器之间有明确的界限。
我正在制作一个简单的游戏作为基于随机事件的练习项目,以便更轻松地添加新事件我决定使用关键字系统,其中每个事件都分配给它们然后使用的关键字要处理事件,这可以像显示消息一样简单,更改模型中的数据或再次随机滚动 table。
我有一个 class 随机决定一个事件和 return 一个带关键字的字符串列表。
我想制作一个 class,其中所有关键字都存储为方法,然后可以使用列表调用这些方法。
像这样:
class Keyword
{
public void InputKeywords(List<string> Ikeywords)
{
foreach (var item in Ikeywords)
{
switch (item)
{
case "keyword0":
keyword0();
break;
case "keyword1":
keyword0();
break;
case "keyword2":
keyword0();
break;
}
}
}
private void keyword0()
{
//do something
}
private void keyword1()
{
//do something
}
private void keyword2()
{
//do something
}
}
现在我面临的问题是从关键字 class 更新模型中的数据。 因为事件是随机选择的,所以我不知道每个事件发送什么数据到 class 让它更新它。
我自己想出的解决方案:
- 使我的模型静态,访问数据不再有问题,Google 告诉我这是不受欢迎的,应该避免。
- 将模型发送到关键字 class,做一些魔术,然后 return 模型。将是一个简单的解决方案,但对我来说感觉不对,从我对 MVVM 的理解来看,应该从视图模型更新数据,但我可能想得太多了。
- 收集所有可能要更改的数据到单独的 class,将其发送到关键字 class,然后更新模型。这听起来很麻烦,感觉就像我只是把问题转移到别处。
我觉得我缺少执行此操作的“正确”方法。 “最佳”方法是什么?
首先,关键字 class 的命名在这里让人感到误导。它基本上是一个事件处理程序,所以我也将其命名为 on(例如 RandomEventGenerator)
对于你的问题,我也不建议你使用静态模型。你的可测试性会受到影响,因为你不会在那里使用依赖注入。话虽如此,您的第二种方法似乎朝着正确的方向发展。我建议使用注入一个 EventInvoker 接口。
public interface IEventInvoker
{
public void RaiseEvent();
}
这可以在操作员中实现,它可以访问您的数据模型并具有预定义的操作来修改您的数据。
public class WeatherOperator : IEventInvoker
{
private readonly WeatherEngine _weatherEngine;
public WeatherOperator(WeatherEngine weatherEngine)
{
_weatherEngine = weatherEngine;
}
public void RaiseEvent()
{
StartSunshine();
}
public void StartSunshine()
{
_weatherEngine.RemoveClouds();
_weatherEngine.SetSunPosition(DayTimes.Noon);
}
public void LetItRain()
{
_weatherEngine.SetCloudes(CloudModes.FullCover);
_weatherEngine.SetRain(RainIntesity.Medium);
}
}
有了 IEventInvoker 的列表,您就可以转到您的 EventHandler。
public class RandomEventGenerator
{
private readonly List<IEventInvoker> _eventInvoker;
private readonly Dictionary<string, Action> _eventDictionary;
public RandomEventGenerator(List<IEventInvoker> eventOperator, List<string> keywords)
{
_eventInvoker = eventOperator;
_eventDictionary = RegisterKeywordsToRandomEvents(keywords);
}
private Dictionary<string,Action> RegisterKeywordsToRandomEvents(List<string> keywords)
{
var eventDictionary = new Dictionary<string, Action>();
foreach (var keyword in keywords)
{
var random = new Random();
var index = random.Next(_eventInvoker.Count);
eventDictionary.Add(keyword,_eventInvoker[index].RaiseEvent);
}
return eventDictionary;
}
public void EventByKeyword(string Keyword)
{
_eventDictionary[Keyword].Invoke();
}
public void RandomEvent()
{
var random = new Random();
var index = random.Next(_eventInvoker.Count);
_eventInvoker[index].RaiseEvent();
}
}
请注意,为了保持小,我没有在此处使用 null 检查或输入验证,这是强烈推荐的。 使用这种方法,您的 model/data 和视图 model/data 访问器之间有明确的界限。