Search code examples
objective-cioscocoasingletonfactory-pattern

Cocoa Singletons and Protocols


I want to define a protocol and create an easy, standard way to grab a 'default', shared implementation of said protocol - singleton style. Cocoa adhere's to the following pattern:

[NSUserDefaults standardUserDefaults]
[NSNotificationCenter defaultCenter]

but in both cases, they have @interfaces at the bottom of the object hierarchy. I'm struggling with how to do this using @protocols. I can obviously create a class that has empty or simple method implementations - but in reality, what I want is a @protocol at the bottom of the hierarchy. I've tried something like:

@protocol ConfigurationManager <NSObject>

//...

@interface ConfigurationManagerFactory : NSObject

+ (id<ConfigurationManager>)sharedConfiguration;

@end

// ...

id<ConfigurationManger> config = [ConfigurationManagerFactory sharedConfiguration];
[config ...];

and it works - but I'm always having to explain how to use this and why I did it this way. Is there a way to conform to Cocoa's syntax (calling convention) while still leveraging the value of @protocols?

As an aside, is there a reason why I wouldn't want to use @protocols like this? The implementing @interface can still leverage categories and alternate implementations, etc - just like how instantiating an NSString usually leaves you with a class extending NSString.


Solution

  • Here's an idea: create your protocol and a class with the same name with a factory method that returns you the default implementation of the protocol:

    @protocol ConfigurationManager <NSObject> ...
    
    @interface ConfigurationManager : NSObject <ConfigurationManager> 
    +(ConfigurationManager *) defaultConfigurationManager;
    ...
    

    Other specialized implementations can then inherit from your base class.