I’d like to wrap a procedural event C API into Objective-C. The procedural API revolves around some opaque pointer, say EventRef
. There are several kinds of events that can be represented by this type – mouse events, keyboard events, etc. You can get the kind of the event by calling some function, say EventGetType(event)
.
It seems very natural to represent the different event kinds by different classes. In other words, have an Event
class and subclasses like MouseEvent
or KeyboardEvent
. My question is how to create instances given some EventRef
?
I can’t simply have a public initializer that takes the EventRef
, as the callers would have to find the correct class before initializing. This feels clumsy:
EventType type = EventGetType(event);
switch (type) {
case EventTypeMouse:
…[[MouseEvent alloc] initWithEvent:event]…
case EventTypeKeyboard:
…[[KeyboardEvent alloc] initWithEvent:event]…
I could do some magic in the Event
ini开发者_运维知识库tializer so that it would pick the right class for the called:
@implementation Event
- (id) initWithEvent: (EventRef) event {
// pick correct subclass, initialize and return that
}
One of the downsides is that this makes subclassing the event types harder. And I don’t like the magic in the initializer. I could also write some kind of registry, but that already feels too complex. How would you go about this? (Please note that the event API is just an example to have something more concrete to reason about.)
The scheme you describe with your magic initializer is a factory pattern. I think it's indeed that way to go, however I wouldn't do it that way but rather:
@interface EventFactory
- (id) eventForEventRef:(EventRef)event;
@end
That is, move the factory to its own class. That way you don't have to mess with the superclass once you add a new subclass.
精彩评论