Вот более сложный, но довольно гибкий подход.Мы определим интерфейс для типа, который может рисовать некоторые события:
interface IEventRenderer
{
// Draw the given event, if it can. Return true if the event was drawn,
// false otherwise.
bool Draw(Event event);
}
Он делает две вещи: он проверяет, может ли он нарисовать данное событие, и, если так, рисует его.В противном случае он возвращает значение false.
Например, класс, который может отображать Sport1Events, выглядит следующим образом:
class Sport1EventRenderer : IEventRenderer
{
public bool Draw(Event event)
{
var sportEvent = event as Sport1Event;
// can only draw this type
if (sportEvent == null) return false;
// draw the event...
return true;
}
}
Затем мы определим класс реестра.Его работа состоит в том, чтобы поддерживать коллекцию этих средств визуализации и передавать работу по рисованию события соответствующему:
class EventRendererRegistry
{
public void Add(IEventRenderer renderer)
{
mRenderers.Add(renderer);
}
public void Draw(Event event)
{
foreach (var renderer in mRenderers)
{
if (renderer.Draw(event)) break;
}
}
private readonly List<IEventRenderer> mRenderers = new List<IEventRenderer>();
}
Все, что он делает - это находит первого средства визуализации, которое может успешно нарисовать событие.Затем вы должны использовать это как:
var registry = new EventRendererRegistry();
registry.Add(new Sport1EventRenderer());
registry.Draw(someEvent);
Плюсы:
- Типы событий не связаны с каким-либо кодом рендеринга.
- Средства визуализациине связаны друг с другом.
- Средства визуализации связаны только с событиями, которые им небезразличны.(Например, Sport2EventRenderer не нужно связывать с Sport1Event.)
- Рендеры могут выполнять произвольную логику, чтобы определить, являются ли они подходящими.Мы просто проводим здесь тестирование типа, но мы могли видеть, реализует ли событие определенный интерфейс, имеет ли определенное свойство, находится в определенном состоянии и т. Д.
- Относительно быстро.Никаких отражений, кроме простого приведения.
Минусы:
- Довольно сложный.
- Может произойти сбой во время выполнения, чтобы найти подходящий рендерер.
- При каждом совпадении приходится перебирать коллекцию рендерера.