开发者

How to create instances when wrapping procedural code into OOP?

开发者 https://www.devze.com 2023-02-15 20:17 出处:网络
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 typ

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消