Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reduce code duplication in my Objective-C code?

I realize this is an overly broad question, but I find that my Objective-C code is highly repetitive. I think the new blocks feature would help, but I can't yet assume that all of my users are on iOS 4.

I often end up with two or three controllers with a lot of similar logic. I do pull some of this logic into a common baseclass, but, especially with delegate-related code, I find very similar logic occurring in several different place because of slight differences.

For example, if I have a UITableViewController and I have several subclasses that use several of the same rows, there is little I can do with inheritance. If a subclass adds an additional row (or multiple rows and/or if they're in the middle of the table rather than at an end), the indexing breaks and most of the delegate methods in the superclass no longer work - I have to reimplement them in the subclass.

Again, I realize this is vague, but what kinds of patterns do people have to avid this from cropping up?

Thanks!

like image 910
Bill Avatar asked Oct 24 '22 17:10

Bill


1 Answers

You are using/thinking-in the wrong design pattern.

Objective-C uses the Delegate design pattern specifically to avoid a proliferation of subclasses. Attributes and identical methods go into a class or limited subclasses while methods that are custom to each use go into a delegate class.

For example, the UITableView class concerns itself only with all the attributes and methods common to every table. All the customization goes in the delegate and the datasource (which is just another delegate) objects. The UITableViewController ties everything into the logical view hierarchy.

If you find yourself with a large number of similar tables, you should create a hierarchy of delegate/datasource classes to handle the changes.

Remember that having the UITableViewController be both the delegate and datasource object is just a convenience and not a requirement. The delegate and the datasource can be in either one or two separate objects which themselves can be in one or more classes.

Tables in particular are highly customized. Each table deals with different data that is displayed in different orders in different cells. That means there really isn't a way to escape writing a relatively large amount of custom code.

Read up on the Delegate Design Pattern.

Update:

If a subclass adds an additional row (or multiple rows and/or if they're in the middle of the table rather than at an end), the indexing breaks and most of the delegate methods in the superclass no longer work

This sounds to me like you are putting model logic in your tableView delegate/datasource. Neither delegate should have to be rewritten just because you add/remove rows or sections. The logic for rows and sections should be in the model object e.g. Core Data, and the delegates should be solely concerned with translating the logical rows and sections of the model into the rows and sections in the tableview. That translation can be done by boilerplate in the vast majority of cases. Any given delegate should be able to display and arbitrary number of different logical tables using the same code.

The only real point of customization is usually the tableview cells. Even then, you are looking at a mere handful of changes per table at the most.

Look at the Xcode template tableview project with Core Data. It can display a vast number of tables without changing any code because all the changes occur in the Core Data model layer.

like image 130
TechZen Avatar answered Oct 31 '22 19:10

TechZen