#c# #design-patterns
#c# #шаблоны проектирования
Вопрос:
Допустим, у меня есть:
public class Buff {
... code ...
}
Затем я реализую триггеры для своего баффа
public interface IBuffOnActionTrigger {
void OnPlayerAction(Player p);
}
public interface IBuffOnPlayerDie {
void OnPlayerDie(Player p);
}
Итак, теперь я могу реализовать эти методы в буфере.
У меня есть следующий метод:
public void TriggerBuffs<TriggerType>(Player p) {
p.Buffs.Where(b => b is TriggerType).ForEach(b => b.<CALLMETHOD>);
}
В этом случае я использую случай переключения
switch typeof(TriggerType):
case IBuffOnPlayerDie:
buff.OnPlayerDie(p);
... etc
Но я искал способ сделать это более элегантно. Какой был бы хороший дизайн для этого?
Ответ №1:
Я думаю, что более простой способ запуска — просто использовать для этого разные методы
public void TriggerActions(Player p)
{
foreach (var buff in p.Buffs.OfType<IBuffOnActionTrigger>()) {
buff.OnPlayerAction(p);
}
}
public void TriggerPlayerDie(Player p)
{
foreach (var buff in p.Buffs.OfType<IBuffOnPlayerDie>()) {
buff.OnPlayerDie(p);
}
}
OfType<T>()
фильтрует буферы, реализующие T, и приводит их к T
, упрощая вызов соответствующего метода.
Обратите внимание, что параметры универсального типа всегда разрешаются во время компиляции, т. Е. Они не обеспечивают динамического поведения во время выполнения. So void TriggerBuffs<TriggerType>(Player p)
не позволяет динамически выбирать триггер.
Если вы хотите это сделать, используйте enum
public enum TriggerType
{
None,
Action,
PlayerDie
}
теперь вы можете динамически вызывать разные типы триггеров:
public void Trigger(TriggerType triggerType, Player p)
{
switch (triggerType) {
case TriggerType.None:
break;
case TriggerType.Action:
TriggerActions(p);
break;
case TriggerType.PlayerDie:
TriggerPlayerDie(p);
break;
default:
break;
}
}