Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

The generally accepted programming practices I've come across tend to advise against big, sprawling classes.

Does using Objective-C categories change the conventional wisdom somehow? Is it more acceptable to have bigger classes if each "subclass" or set of tasks is in its own category? In my own experience, I've found that where I might've in the past tried to split classes, I now sometimes find it easier and rather maintainable to just split categories, but am I setting myself up for future maintenance hell (or other kinds of hell) by doing this?

share|improve this question
1  
I try to keep the core functionality of the class in the main part, and only put extensions in categories. Generally, a subclass should be able to substitute the whole class by overriding all the functions in the main part.I believe that's the philosophy of categories. –  Per Johansson Aug 8 '11 at 8:53
add comment

4 Answers

First, using categories does not make your class smaller, it just hides how big your class is by spreading the code into several files. There are some times where your class can't be smaller (think of NSString) because it really needs a lot of methods. But I'm pretty sure that most of the time those big classes can be smaller.

When a class is too big, it's not only a readability issue. One of the reasons why a class becomes too big is that it violates the Single Responsibility Principle or other object oriented design principles.

My advice is : instead of trying to reduce the size of your files (by using categories or other tricks), you should focus on class responsibilities. Usually, by simply following the Single Responsability Principle and other good object oriented practices your classes will split naturally into other classes (and not files). Not only will it reduce the number of line of code by classes, but it should also bring more testable and reusable classes.

share|improve this answer
add comment

The first versions of my classes where filled with sprawling methods and definitions for anything that class implemented. Maintaining it was hell. All of my methods were getting lost. They were organized by #pragma marks, but the .m file was just to big. A lot of my methods would be half commented out with new functionality I would think of adding at one point but change my mind halfway through. It was way too much mental overhead.

I rewrote the code to have a view subclass that did the basic layout and management of my subviews (some of which were also custom views.) I kept the functionality really small and started subclassing my custom view for additional functionalities. I ended up with stuff like MenuedCustomView, OverlayCustomView, GradientCustomView. This was a huge improvement.

First, I could go back to the base sub class and really refine it's respoinsibilities and make it super tightly architected. Second, testing out new functionality was easy and clean. I would make a subclass add the functionality, then change a #define symbol in my controller to, say, TestCustomView or back to GradientCustomView or whatever. This Class swapping was a tiny bit unwieldy, but certainly worked better than when I was just working in the same class definition, adding functionality, trying them, reverting them, all in the same .m file. I have subclasses that have stubs of additional functionality I would like to add in the future, I'm just not including them in my Controller class. When I feel like working no them it's super easy to add to my project.

A little bit after I started subclassing everything I learned that this maybe isn't always the best practice in Objective-C and cocoa. I switched to adding categories for a lot of additional functionality I wanted to add to a class. Of course categories only add methods and not properties, so some of the functionality I was adding was only possible in a subclass. Now, I've now got a mixture of subclasses and categories to define my objects in a mostly manageable and easy to read/maintain file/class hierarchy.

I've wondered how Apple maintains a class like NSString. Is it one large .m file? Do they have a bunch of ProtoString classes that each add separate functionality and then they inherit them into the one NSString class? Or is it a base set of functions and then a bunch of categories?

I've still got a bunch to learn on the high level architecture of a good cocoa app, just thought I'd share my progression.

share|improve this answer
add comment

Do you talk around categories for your own classes, or for Foundation, etc?

First, you have to decide, if you really need categories. Second, if you plan to share your code, you have to go for conventions - as people who use your categories may never look into code. If you suppose mainteanance hell - ask yourself - why? Probably you can do better with current code.

Anyway, I'd recommend to not access class variavbles directly by using categories - use properties and messages, take care on not changig the object by your code, if possible.

Document your code, at least, headers - this might help anyone who will have to use or refactor them later.

share|improve this answer
add comment

One defense against sprawling classes is rounding them up in a folder and Xcode group. That doesn't solve the problem in code, but it greatly helps organize the files on disk.

For instance, you may have a folder of UIKit categories, a folder for a specific part of your application, etc.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.