During a phone interview I had with Web M.D. recently (it started as a lightly technical interview and then I was thrown a curve ball - see the bottom for more) I was asked to define a category and explain when I'd use one. I gave an answer, but more importantly, I gave my answer. The interviewer responded with his own answer, and from the way he explained it, that was the answer he was looking for.
In reflecting back on that interview question, I would disagree with that my interviewer said about categories. He told me that "they should primarily be used when you don't have access to the source code of a class". While I agree that categories provide a useful way to extend functionality of classes that we don't have the source code for, there is no single right answer to this question. Categories can be useful in other ways, and can be less useful in just as many ways. In disagreeing with my interviewer (which I didn't express during the interview, although thinking back on it, I definitely should have), I'll list some of my ideas here:
- If you need to add functionality to a class but don't have access to the source code, use a category.
- If you need to add data to an existing class (properties or ivars), don't use categories, and instead just subclass and make use of inheritance. I say this because categories don't support adding properties or ivars (unless making use of associated objects, which I won't get into here).
- If you have a totally oversized, bloated implementation file, consider breaking up the class into specific units by using categories.
- If you want to provide some pseudo level of encapsulation, you can add "private" methods to a category and only selectively import that category filename. However, this isn't the only way to mimic encapsulation (you can use extensions, for example), so take this one with a pinch of salt.
- If you have instance of a specific class littered throughout your source code and suddenly need to add functionality to that class, use a category. Your alternative would be to create a subclass, add new methods, and then replace all of your instance with the new subclass. Inefficient, to say the least. This works to your benefit in (sort-of) reverse - if you have instances of a subclass somewhere, adding methods to the parent class through a category trickles down to the subclasses.
- If you absolutely, 100% do not need to create a parent-child object hierarchy, use a category.
The interview question I got that really shut me down was about graphing a curve using data points representing pollen levels. The interviewer was explaining to me that there are certain things a seasoned developer with a computer science degree would know how to do that I wouldn't (I have a degree in Environmental Science, which involved high level math and science coursework). To be totally honest, I think that even if I had majored in CS, I wouldn't have remembered anything about plotting points using bezier curves and the De Casteljau algorithm. Unfortunately, I was relayed the information that although I seemed to be a solid candidate, I wasn't technically experienced enough to join the team and hit the ground running. On to the next.