I write PHP
For some time, I’ve complained about object oriented programming (OOP). These days I program in PHP almost exclusively, and in that context, OOP is only mildly advantageous. However I just watched a video from a guy trying to make the case that OOP is garbage (Brian Will), and he did so in an entirely different context.
Mr. Will codes in a variety of languages, but in the context in which he programs, classes are often closely tied to variable types. One of the original selling points of OOP was that it was a convenient way to neatly implement synthetic or artificial types. You could create, for example, a circle type, and implement a variety of methods connected with that type. His point was not that that was a bad idea, but that it tends to become pervasive with programmers. They tend to want to “classify” everything in a program.
But the context in which he was talking caught my attention. In his programming universe, types were intimately connected with classes, something that is almost never the case in PHP. But I can see where this would be the case in C++, Java and a variety of other languages which solve different kinds of problems than PHP.
Some years ago, I wrote a library to deal with dBase/FoxPro files, called “DBF Swiss Army Knife (DBFSAK)”. Originally, I wrote it in C. But then I thought that C++ might be a better choice. The rationale was that much of the program was just code to do something to a DBF file (read the header, show the fields, etc.). But the functions which dealt directly with the DBF were very specific to that “type” and so could be easily slotted into a class. Moreover, the class could carry around a copy of the DBF header, so that other methods could simply access that in order to do their work.
This was a reasonable conclusion, and reasonable programming practice. But C++ is a quirky language with obscure rules when it comes to dealing with classes and objects. It was, after all, a “bolt-on” on the C language to allow it to do OOP. And C just wasn’t built for that purpose. Ultimately, I found it too much of a pain in the ass to maintain the code in C++, and converted it back to C. All the class methods were turned in to functions with the prefix “dbf_”. There weren’t that many of them, so it wasn’t that tough a change. And I implemented a “global” variable to hold the DBF header information. This was passed to the various dbf_ routines on the stack, just like any other function.
Where classes are intimately associated with a type, I can see good reasons to create classes surrounding the type. Mr. Will made a lot of very salient points about how this type of thing is abused and overdone by programmers, making OOP almost worthless. I can see that, too.
Unfortunately, I don’t work in the same world he does. I work in the realm of web pages and PHP and model-view-controller (MVC). There aren’t “types” which I deal with that need a raft of functions specific to them. I implement OOP primarily in the model. The view obviously has nothing to do with objects. And the controller just coordinates between the view, the model and the user. No need for classes there.
But I began to wonder what it would be like to convert one of my models to strictly procedural code. I would need to define one or more global variables to hold values the model uses with multiple functions/methods. I would probably want to prefix the functions with something like “blog_” to sharply delineate what is and isn’t part of the model. Overall, the changes would really be minor. The largest problem would be whether to pass globals on the stack, or simply add a “global” declaration at the top of the functions. That gets into a hairy debate among programmers and computer science professors.
The best example I’ve ever come across of high quality code which avoids OOP is Drupal. Drupal is a PHP toolkit for building websites. Through version 6, it included no OOP whatsoever. And the code was and is brilliant. The design is incredibly well thought out and implemented. And yet, for that version and before, there isn’t a class anywhere in sight. From version 7 onward, the Drupal team gradually implemented classes. But Drupal’s documentation makes the valid point that, even without explicit classes, Drupal’s design include numerous examples of object oriented design and behavior, even without the presence of explicit classes.
Given the examples of DBFSAK and Drupal, it’s easy to see that code can be written with explicit classes or not, and still be quite efficient and functional. I make this statement in the context of web pages and PHP. And in that context, the difference between object oriented and procedural code is mostly one of style. If you don’t want your friends to rag on you about your lack of module classes, define some. Personally, one of the things that bothered me about C was that you always had to feed any function parameters to the function explicitly. There was no such thing as a true “global” variable. And I hated C functions where I had to put large numbers of variables on the stack for the function to see. You could pass pointers to the global variables, but C pointer syntax trips up more programmers than almost anything else in C.
My objections to OOP come from the context of the PHP language. PHP has a weak implementation of the core principles of OOP. For example, real encapsulation requires you to make properties and methods private. Otherwise, some programmer can just reach in and manipulate internal class values, no matter how many setter and getter methods you write. Of course, you can declare things private, but it’s not the default. Inheritance is very limited in PHP (and frankly isn’t really needed much, if at all).
In any case OOP in PHP mostly has the benefit of implementing “namespaces” (which the language recently adopted), and allowing variables to be carried around and shared easily within a class. That is, OOP in PHP is mostly about encapsulation and nothing else. In fact, I could legitimately say that that is the sole reason I have for using OOP.
On the other hand, for other types of programming, OOP can be about a lot more. But I agree with Mr. Will’s point. Coders get carried away with OOP and infuse their code with far too much of it. Moreover, polymorphism and abstraction are not very useful in OOP, so you’re mostly looking at encapsulation and inheritance as the remaining benefits for OOP. And inheritance is rarely used for the most part. You could implement a “shape” class, with circle and ellipse inheriting methods, but such an example is rare.
Mr. Will made a point that OOP has profound implications for state. A group of objects which are capable of changing each other’s state actually damage the concept of preserving and isolating state. To me “state” is an academic concept which doesn’t have much value in the real world. But then, I program in PHP. From his perspective, programming in his contexts, I can see the importance of maintaining the sanctity of state.
So my objections to OOP are the more strident simply because I use PHP. Most of the problems OOP is meant to solve don’t exist in PHP code. For other languages and contexts, OOP can play a more active role. But it’s worth nagging programmers that they should confine OOP to only those specific programming contexts where it’s truly advantageous. Otherwise you’re just coding to satisfy some university professor’s idea of what code should look like.
Again, OOP is just another fad (albeit a long running one), like agile programming and functional programming. All fads have some value in certain contexts, but that value is far more limited than professors would have you believe. And I’ve never seen a fad fulfill the promises it proclaimed. Use what works, and discard the rest.