I know there’s a lot not to like about object oriented programming. It can be more difficult to debug than functionally-oriented scripts. It has side effects up the wazoo if programmers get lazy. Especially in large code bases with a long history, inheritance tends to layered-up.
This is all on my mind because I spent the day refactoring ZFPlotExtension, a lightweight set of custom graphing classes designed to make simple line charts, scatter plots, and bar graphs. I’d done the bad/lazy thing of initially packing MV&C into one 1100 line class. There have been worse things, but it was far clunkier and more repetitive than it should have been, and enough of a mess that I didn’t want to look at it for awhile. But today I screwed up my courage and dove into the morass.
Objective-C often feels designed to the core to encourage MVC design, particularly with all the iOS SDKs, so I found it was breeze to pull out my model and view. I moved all the data-oriented logic in a ZFData class with a weak property pointing back to the parent ZFPlot class for when I’d need physical layout parameters to make data-related calculations. Easier still, I moved all the drawing (think CGContexts floating around) to a ZFDrawingUtility where functions like drawCircle and drawLine were clearly logically encompassed as a drawing utility that actually didn’t even need access to the physical layout parameters stored in the parent class.
Easy part done, I turned to the difficult part, which was finding a way to make three plot classes out of the single jerry-rigged plotting class I had currently, which used a hacky self.chartType property setting to indicate what kind of chart was wanted.
The difficulty was that Objective-C does not suppose anything like abstract base classes, though an abstract base class was exactly what I wanted. Or rather what I wanted was a mostly-abstract base class, where universal functionality (drawing axes, closing the box around the plot, animating the drawing of segments) could be concentrated, whereas sub-classes could put the finishing details in.
With C++, this would have been a piece of cake because adjusting the privacy level of a member function for client and/or inheritance purposes is as simple as changing a method from private to protected or public. With Objective-C, only public functions can be inherited, which means I had to write public declarations for all the functions I wanted inherited and/or overridden (which was a handful * 3 = feels like a lot). I couldn’t even find any within-Xcode functionality to do this automatically.
Apart from the difficulty of adjusting the privacy level and inheritance eligibility of class methods posted by Objective-C, there’s an even more gaping hole. You have to do all the book-keeping about whether you’ve overridden the class you need to override in your subclass without any help from the compiler. There’s no such thing as abstract base classes in Objective -C ( see this Stack Overflow post ), and perhaps more disappointingly is that Switft also lacks this capability (see this SO post).
Sometimes it seems as though the structure of the language Apple chooses to offer its developers affects how those developers think. When I do ask questions about inheritance in Objective-C on Stack Overflow, I find the answers a bewildering mix of anti-inheritance propaganda and pro-protocol hysteria. Ok, I am clearly exaggerating more than a little, but I don’t understand why app developers, who do more repetitive GUI-related work than anyone else, can’t see the glorious possibilities of easy inheritance mechanisms, including multiple inheritance and abstract base classes. I often find myself thinking how much faster and better organized my work could be if these mechanisms were available.
The not-so-satisfying solution is of course to declare a protocol, write classes to fit that protocol, and in this way be driven towards a solution that leans heavily towards composition rather than inheritance. I’ve no doubt this is good much of the time, but wouldn’t it be nice to have more freedom?
Now that I’ve learned enough about Swift to learn that it repeats Objective-C’s sins vis-a-vis OOP patterns, I must admit that I’m far less eager to learn it. When will iOS have a real programming language with all of C++’s flexibility and power?