A small thought on Objective-C categories


I recently hit what seems to me a cute little example of how Objective-C Categories might be used. If you are unfamiliar with them, the Apple docs are good. They are often used to extend pre-existing classes from Apple i.e. where you don’t have the source code.

I had what could be termed a Domain Model in an iOS project. It did not know anything about the user interface, naturally. There came a point where the Model was to be connected into the UI. The UI was already written to use a C-style enumeration of Model types (when the UIPickerView presented different values to choose from, and the UI code handled the user’s pick).

The Model had no internal need for a categorized, constrained list of the domain types. If you have seen things like the expression problem or a visitor design, you will probably have thought about where to put code. It is not always an easy thing to decide. In my case, the Model was a fine fit for regular OO where you can add new types implementing a standard set of methods, rather than something ‘procedural’ or ‘functional’ where you have a fixed set of types and are more interested in adding new methods for all of them.

Anyway, I simply added an enumeration directly in the Model layer. Each Model class exposed a read-only property of that enumeration type. Problem solved; the UI could get on with life. There are times when you cannot or don’t want to boil the ocean.

But if one had a strong urge to avoid putting UI knowledge inside the base level of the Domain, how to do it? Something that came to mind was to use Categories: extend the Domain classes with the enum property for UI consumption, leaving the base Domain classes alone. Given how the project was already going, the overhead would be an extra pair of files (one .h, one .m) per Domain class, of which there are only 3 since it is a small R&D project. Each of those files would be pretty succinct. Additionally, the UI files would change their imports from e.g. “DomainModelClassX.h” to “DomainModelClassX+TypeEnumeration.h”.

The advantage is that the base Domain code still doesn’t know anything about this enumeration, while the UI gets what it wants. Disadvantages include there being more files in the project (not an inherent evil, but something to be wary of); that the UI code needs to know the right files to import; and that concerns are split across several files (future developers might find this design obscure vs. the enum-in-Model approach). When I consider that the Categories could pull out further UI-Model specific code like display strings for the various Model types, I’m even more attracted to the Category approach. It seems like a pretty nice way to make the two layers meet.

There are of course other ways to wrestle with all this in Objective-C, let alone other languages. Scala, Perl, and PHP support traits. C# supports extension methods. Lisps support multimethods. (You could probably even perversely use an Aspect Oriented Programming library to address the issues.) Some of those languages also offer stronger static typing than Objective-C in this arena, if that floats your particular boat.