我定义了一个Event类:
Event
并且所有以下类都继承自Event:
SportEventType1 SportEventType2 SportEventType3 SportEventType4
现在我只会参加SportEvents但是我不知道将来我是否会想要其他一些与体育没有任何关系的活动。
稍后,我将想要绘制一些带有从事件中获取的信息的图形,并且绘图逻辑可能有点复杂。但是,目前,我认为我不应该想到绘图将如何完成,我相信如果绘图部分不是作为Event / SportEventX类链的一个组成部分,那也许会更好。 / p>
我正在寻找这个问题的解决方案。我知道我可以让Event有一个实例变量(属性,对于java crowds)指向某个IDrawInterface,但这会使Event类“假设”它将在以后用于绘图。如果可能的话,我想让Event类忘记这一点。
谢谢!
答案 0 :(得分:3)
您打算在Event类层次结构之外保持绘图过程的知识是好的。
在OO语言中处理此类事物的常用方法是Visitor Pattern。
如果您无法实际更改Event类以添加访问者所需的accept(Visitor v)
,则可以考虑使用Decorator或Adapter。尽管如此,让accept方法因子类而异,可能会让人感到痛苦。我会考虑更多这一点,也许今晚可以补充说明。现在,我必须开始工作。
答案 1 :(得分:1)
另一个解决方案可能是拥有一个DrawbleEvent抽象类,其中不同的sportchevents可以继承。
public abstract DrawableEvent
{
Event event;
IDrawingStrategy drawingstrategy;
public Draw()
{
drawingStrategy.Draw();
}
}
public SportingEvent1 : DrawableEvent
{
SprortingEvent1(Event event, IdrawingStrategy strategy)
{
this.event=event;
this.drawingstrategy = strategy;
}
}
事件参考可以根据需要的位置转到策略或sprorting事件。
答案 2 :(得分:1)
这是一种更复杂但非常灵活的方法。我们将定义一个接口 对于可以绘制某些事件的类型:
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);
<强>优点:
<强>缺点: