Object oriented programming is okay, but...
In keeping with my native iconoclasm, let me now knock Object Oriented Programming. No, I’m not completely against OOP at all. I use it quite a bit. What I object to is the tendency among programmers to worship the ground that OOP walks on.
Before I get to the meat of my arguments, let me point out something. Most of the great computer languages of yesteryear are either rarely used today, or are used in purely niche areas. Try to find programs written in P/L-1, AP/L, Algol and the like. Good luck. Some of the older languages are still in use. I don’t know for sure, but I suspect that Fortran, COBOL and Ada are still in use in various places. But as I said, these are primarily niche uses. BASIC is still in use, but the BASIC you see today is a helluva lot different from the original conception of BASIC.
So what language(s) emerged from the olden days to be in regular use today? Mainly C. In fact, C is the preferred language for the compilers and interpreters of most other languages. Moreover, C is the language in which most serious operating systems are written in. And a wide variety of languages in popular use today stole masses of syntax and structure from the C language.
What’s my point? The C language has emerged as one of the most popular, useful and critical languages in the world today. And C has not a drop of object orientation in it. The world has gotten along without OOP in writing a tremendous amount of very useful and vital code. So OOP’s not the panacea many would have you believe.
Yes, there was a bolt-on pre-processor driven OOP variant of C created called C++. Later its reliance on the preprocessor was lessened or removed. And it, too was heavily imitated. But it has not seen the amount of use, particularly in fundamental applications like operating systems, that C has.
Okay. object oriented programming is supposed to have a variety of advantages over non-OOP languages. One of the most touted advantages original touted for OOP was its presume reusability. Gurus envisioned write-once-run-everywhere which would obviate the need for all kinds of unique code written for various purposes. But programmers being programmers, it didn’t work out that way. There’s no world-wide registry of universal classes which make your coffee and parse English at the same time. I guess the authorities thought that object oriented programming and languages would change the fundamental character of programmers. Not so much.
The next advantage of OOP was encapsulation. The idea was that you could write the methods of a class, and to the outside world, they would appear as black boxes whose workings you didn’t need to know about. And if you needed to change the way the methods operated internally, you could do that without forcing a change on the way they were used by external routines.
This supposed advantage is of questionable value. For example, I could write a class which handles imaginary numbers, with a variety of methods for adding, subtracting, dividing and multiplying imaginary numbers. I could later come back and change the way the code for multiplying imaginary numbers works internally, and you wouldn’t need to know I did that, as long as it gave the same correct answers as before. But here’s the thing. I could do the same thing with a series of independent functions which did the same thing. And I could come back later and change the internal code for the multiplication one, just as I did for the multiplication method of the imaginary number class.
Encapsulation also implies that certain (usually internal) methods of a class can be cut off from use by external programs. Well, okay, but I’m not sure that’s a huge advantage either. You could simply write an independent non-OOP to do something to imaginary numbers and then put a big comment above it in the code which says, “Don’t call this routine!”. If the programmer then went ahead and ran it, he or she would do so at their own risk. No big deal.
Now, here’s one argument I will make in favor of OOP and it’s a very important argument. The larger a project gets, the more crowded the namespace around it gets. Object classes resolve this problem rather handily. Method names inside a class are only accessible in the context of the class itself. They are not directly callable without reference to the class which contains them. This kind of thing is very important as projects become larger. Moreover, instead of having to give functions long names like “imaginary_number_multiply()”, you can just say “inum->multiply()” or “inum.multiply()”. It’s a lot cleaner and a lot simpler. And I’ll admit that the ability to hide certain methods as private within classes adds a bit of safety to your code.
Next up, inheritance. In essence, you can create a class with part of the attributes and behaviors you want, and then have another class inherit those attributes and behaviors, while adding its own to the mix. It’s a nice idea, and sometimes useful. But less useful than you might imagine. I’ve rarely written hierarchies of inheriting classes for any project. When it’s called for, it’s useful. It’s just not called for that much. When it’s needed, it can save on coding I suppose, since you don’t have to duplicate the code in every child class which derives from the parent class. On the other hand, a set of standalone functions called by other functions can accomplish the same purpose.
One other argument I’ll make in favor of OOP, which is vaguely related to the above is the ability of classes to save the stack from overwork. Objects can store lots of information when doesn’t then have to be passed on the stack to every method which needs the information. Contrast this with standalone functions, which virtually always have to have their arguments (or pointers to them) passed on the stack. For example, if you had a function to multiply imaginary numbers, you would have to pass both numbers on the stack to the function. But an imaginary number class might not need that. It could store numbers and operate on them with various methods, without having to pass them individually to the methods.
Now, to be fair, structures in C have the ability to store both data and function pointers, making them in theory equivalent to class objects in this respect. The problem is that not all languages which are similar to C have this capability. And even in C, this is a really clunky way to do things. Classes are a much simpler solution when it comes to this.
Lastly, there’s polymorphism. Polymorphism actually resembles inheritance in some ways, and often requires it. With polymorphism, an object can act differently depending on the context in which it operates. It can also appear to “masquerade” as something it isn’t just to make things simple for the programmer. For example, a string class can be coded so that when faced with a plus sign (+) it will concatenate two strings. Otherwise, the concatenation of two strings can be rather complicated and require verbose coding.
Now, while I’ve coded in C++ before and used polymorphism in that context, I normally code in PHP these days. PHP has very weak support for both polymorphism and inheritance. So I can’t use it much anyway. But I would venture that the circumstances in which one might need to use polymorphism are generally limited. Of course, a programmer could program a class such that it used the plus sign to signify painting a graphic red if he wanted to. It would be a valid but silly abuse of polymorphism.
And this is another point I’d make about OOP. Using object oriented languages and object oriented programming tends to make programmers craft solutions which take advantage of objects and classes. This is fine, but in many cases, it’s really overkill. The same exact things could be accomplished using other methods. But OOP shapes the way a programmer thinks about solutions to problems. I know that when I’m coding in C++, I often find myself asking, “What around here should I be making into a class?”
As I said in the beginning, I’m not knocking OOP completely. I’ve made some arguments in favor of OOP. Sometimes, it’s the right solution. In fact, almost every time I code a website these days, I use a the Model-View-Controller paradigm. And when I do, I invariably create a controller which is a single class with a variety of methods designed to do what I need. It’s an obvious use for OOP.
All I’m saying is that OOP is not a panacea, and it certainly isn’t all it’s been cracked up to be. Use it where it’s needed. Avoid it where it’s not.