Domanda

I have a plugin architecture for my desktop app. I've implemented it in a fairly standard way using Apple's code loading guide.

I have a single protocol which defines all the methods an instance of the plugin can or should respond to.

The only problem is this protocol defines around 80 methods. Only about 10 of these methods are compulsory and the rest are optional. Some plugins will implement all 80 methods, whereas others will only implement the basic 10.

The usual way for a plugin bundle to tell its host application which class to instantiate is via the NSPrincipalClass key in its Info.plist file. This is a single key so only a single class can be instantiated.

The plugin protocol is a single file and its expected that it will be used by this single class.

My question is: what is the best way of splitting up the functionality inside this single protocol into perhaps multiple protocols, whilst at the same time allowing the plugin writer to have a more flexible implementation?

Currently my existing plugins have the following in their principal class:

- (BOOL)respondsToSelector:(SEL)selector {
    return [self forwardingTargetForSelector:selector] ? YES : NO;
}

- (id)forwardingTargetForSelector:(SEL)selector {
    id target = nil;
    if ([self.instanceOne respondsToSelector:selector]) {
        target = self.instanceOne;
    } else if ([self.instanceTwo respondsToSelector:selector]) {
        target = self.instanceTwo;
    } else if ([self.instanceThree respondsToSelector:selector]) {
        target = self.instanceThree;
    }

    return target;
}

But rather than imposing it upon the plugin writer to define an ad hoc system like this, I would like the application's plugin framework to accomodate a more flexible solution.

È stato utile?

Soluzione

If you can divide your 80 methods into sensible chunks of functionality, you could split them up into several protocols (FooProtcol, BarProtocol, etc.) and define optional properties that return references to objects that implement them in your primary protocol. For example:

@protocol PluginPrimaryProtocol <NSObject>
@required
/* ... */
@optional
@property (readonly) id<FooProtocol> fooDelegate;
@property (readonly) id<BarProtocol> barDelegate;
/* ... */
@end
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top