Objective-C Protocols – Programming Against a Protocol

interfacesobjective cprotocolsolid

I stumbled accross the SOLID principles. There is one burning question. Should I always use protocols? I never saw someone using them in the way that a Java developer would use them.

I tried it in a demo project and ended up with a .h file for the protocol, another .h for the header. A .m file for the implementation and sometimes a .xib for the UI.

Is there a reason why an ObjC developer would only use protocols for delegates? I never saw ObjC code with a test first approach. Does SOLID programming apply for ObjC?

Best Answer

TDD isn't hugely popular in the ObjC world. Look at some of the official Apple SDK libraries and you'll find patterns that would make TDD advocates give up in disgust (there are a lot of singletons in the iOS SDK, and it's a pattern that works very well with ObjC). Unit tests in general aren't that popular, either, which explains why the official unit test suite is a relatively recent edition to Xcode and why it's still third-rate. The ObjC philosophy seems to be:

"Don't make your code more complicated in order to write tests: simple code is easier to debug."

That'll undoubtedly rattle the TDD guys, but it's the approach I've noted in ObjC developers.

ObjC takes a more pragmatic approach to protocols than Java devs do to interfaces ("every class must have an interface and an implementation, just in case!"):

  • If you know that you'll need multiple classes with the same interface and want the compiler's help, you can create a protocol.
  • If you know that you'll need multiple classes with the same interface but don't care about support from the compiler, you can use "informal protocols" (take a look at how to handle data from a GKSession object: you implement a method, not a protocol).
  • If you're probably only going to use one class, just use the class and forget about protocols.

This is why you only tend to see protocols used in conjunction with delegates: they tend to be the only places that you'll create more than one class to implement the necessary functionality, especially as the delegate pattern is so pervasive. Other languages tend to require you to either subclass and override or implement an interface to provide additional functionality; ObjC tends to use delegates instead.

The fact that ObjC is dynamic removes a lot of the need for protocols/interfaces. Java, C++ and C# developers spend a lot of time trying to categorize and type everything as accurately as they can, resulting in multitudes of interfaces and classes. That simply isn't necessary in a dynamic language (and it's one of the reasons I'm so happy to have switched from C# to ObjC: I can spend my time solving problems instead of describing type hierarchies).

ObjC is dynamic and supports duck typing, so if an object implements a method "quack" you can call that method without explicitly conforming to the "Duck" protocol; you can even identify if the object implements the method before calling it thanks to ObjC's excellent metaprogramming capabilities.

Related Topic