I remember when in early 1990s some of my programming friends told me how excited they were about a new paradigm of object oriented programming (OOP) and when everyone started using C++. Borland was fighting with Microsoft over better C++ compiler and from what we see today Microsoft has won with C++, then started losing against Java, then created C#. As I remember, part of the excitement with OOP, was due to the OOP helping us, developers, make less coding mistakes. For example forcing strongly typed objects and variables, letting us group related functions and variables into related objects, replace variables with object properties, and replace functions with object-specific methods. I went with the flow and learned some of the OOP concepts. One common early example used to teach OOP was of a circle being an object that has some properties like .radius and .shape, explaining how such properties can easily be defined and later manipulated, even shared with certain other objects like an ellipse. Since then object oriented programming has evolved into very complex structures and advanced applications, including most of the apps and frameworks being in use today. OOP features and concepts have further evolved and matured over the years. At some point those concepts have exceeded my ability to understand OOP and program because my code looked poor comparing with everyone else’s. Thus instead of coding, I started delegating and relying on other people doing coding for me. For example here is some OOP code written by our developers at my company, which looks like total black magic to me:
public class Record : DataBoundControl, IForm, INamingContainer, IErrorHandler, IErrorProducer, IValidator, IClientScriptHelper, IMTAttributeAccessor
public IForm OwnerForm
Control _owner = Parent;
while (_owner != null && !(_owner is IForm))
_owner = _owner.Parent;
public virtual ITemplate ItemTemplate
_item = value;
Now, if a programmer writes object.value=”OOP”; print object.value; then at least I can see what’s going on, but various mixed classes, interfaces, inheritances and other OOP bs is just too much for me to swallow. And it’s especially too much because I do know how to code better than most developers out there in terms of efficiency, clarity, and achieving desired results, and I can create very advanced apps with procedural coding without all the OOP crap.
In any case, my approach of being hands off and delegating writing code to others turned out to be successful because we had great developers who created great software, but in the end I was never completely satisfied since I couldn’t take full control of the code, dig into it, and create more amazing stuff I knew I’d be able to do if I had full understanding and therefore ownership of the code. I could also be more helpful in structuring better application architecture and features, and making it more stable, by being hands-on and part of the coding team. In the end, I consider my own inability to code OOP a disaster because for many years I thought I just wasn’t skilled enough to code and others could code much better. If I only could get my hands dirty and code with my team, we could definitely create even more amazing products.
What’s more, I also noticed that this holds true for thousands of our customers, who were also developers who found OOP concepts too difficult to utilize. In fact, our first product was a software development tool for developers. The tool itself was written in C++ in OOP, and it was/is outputting OOP code, while it exposed various events to programmers who could then add additional functions to the code output, for example to send an email after a record was added or updated in the database. And what I’ve noticed is that, just like myself, possibly all of developers who were our customers would have difficulties understanding the object oriented code created by the tool, but would be fully capable of creating wonders by happily coding procedurally and extending their applications to the max. They’d simply insert procedural code to the places in OOP code we’d exposed to them. This not only shows that some developers can do wonders when given the right tool, but it also shows that many more people are capable of programming than those that understand OOP. We, procedural programmers, only need the right tool and a push into the right direction, and we can put OOP to shame.
Finally, last year I myself started getting back into coding and creating couple new apps fully based on procedural code in C#, without using OOP. And then I discovered the true power of coding, and the true power of my abilities. Because the applications I’m working on are so advanced, so elastic, so polymorphic, so highly parameterized, so mendable, so maintainable, so compact, so learnable and so fast performing, that I don’t think any OOP developer would even come up with some of the concepts I’m utilizing. Simply because they’d be too limited and blinded by OOP principles they’ve learned. In fact, I did try several times to have these applications written by various developers, yet no one fully understood what I need and everyone tried to approach it wrong way. I did look at their initial OOP code, I did understood it, I was able to modify and extend it, but each time I arrived at conclusion that the OOP code was unnecessary, added to confusion, and actually limited our system architecture to some extent. That’s partially because we use dictionaries for caching certain data (similarly to Dapper), but in our case we also store database structure definition and connection parameters in a dictionary, as well as track open connections via that dictionary. And the object-oriented way of defining entities, database fields, field parameters, even database connections just didn’t fit. For example we didn’t need to duplicate connection properties in both our global dictionary and Connection class, or define entities in classes when we also stored their definition in the database and built them dynamically. To some extent we were emulating objects, so trying to use OOP to emulate OOP didn’t make sense. While OOP developers wouldn’t even come up with ideas how to emulate OOP because they are so used to defining objects and needing to design a system in specific way. To me, all this just looked like unnecessary, redundant, and confusing code, no matter how cleanly it’d be implemented in OOP. And although OOP did fit better in some scenarios and parts of our system, I simply got fed up with object properties being defined outside of functions, classes needing to be instantiated, some Tuples where I didn’t need a Tuple, and other noise I didn’t need and didn’t have in my basic procedural programming. And every time I was getting stuck unable to do something I needed, or waiting for our developers to redesign something in OOP which I already had working perfectly well without OOP and implemented 10x faster. Instead of moving forward, I’d do couple a few hours of work and then wait two days for someone else to convert it to OOP. And each time I got fed up and had to wrangle the control back and set the development back on the right track using my own style of procedural programming. In the end my procedural applications can do more with much less code, and I can program much faster than anyone else. My code also looks simpler, is well commented and probably performs better than OOP. And I’m hoping to create something that could benefit all of us procedural coders, thus if all goes well I may open source it in the future.
Through all this recent experience I discovered, again, that I can create excellent code and it doesn’t need to be OOP. I also discovered, again, that I love to code. At the same time, now I believe OOP can be bad for coding. At least for me it turned out disastrous because for many years it made me assume I need to know OOP to be a great developer.
Recently I also discovered an important difference between OOP and procedural/functional coding: when you code OOP you may spend quite a lot of time designing the code, while when you code procedurally/functionally you simply focus on writing the code and you don’t even need to think about design because it comes naturally. You need your code to do something so you simply do it, not try to figure out how it should be designed so that later something can happen. This difference explains why I usually have to wait for developers to do something that I’d already have done several times over and in several programming languages. Thus for me code design is a thorn in OOP.
And today I found that OOP may be enjoying such a wide acceptance partly because of the silly strong typing and other code design features that so many people rave about. Because, you see, strong typing and some of the OOP features are indeed useful when you are a mediocre programmer and need an environment and tools that will allow you to do less damage. At least that’s how it looks based on Wikipedia:
Here are some quotes:
“Paul Graham has suggested that OOP’s popularity within large companies is due to “large (and frequently changing) groups of mediocre programmers”. According to Graham, the discipline imposed by OOP prevents any one programmer from “doing too much damage.”
“A study by Potok et al. has shown no significant difference in productivity between OOP and procedural approaches.”
“Luca Cardelli has claimed that OOP code is “intrinsically less efficient” than procedural code, that OOP can take longer to compile, and that OOP languages have “extremely poor modularity properties with respect to class extension and modification”, and tend to be extremely complex”
“The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.”
“In an article Lawrence Krubner claimed that compared to other languages (LISP dialects, functional languages, etc.) OOP languages have no unique strengths, and inflict a heavy burden of unneeded complexity.”
“Rich Hickey, creator of Clojure, described object systems as overly simplistic models of the real world. He emphasized the inability of OOP to model time properly, which is getting increasingly problematic as software systems become more concurrent”
“Object-oriented programming languages tend to encourage thickly layered programs that destroy transparency”
In retrospect, I can see how I fell into the OOP trap, where so many people got excited about something that really has no value if you know what you’re doing. While in fact, OOP may even have negative value, as it keeps potentially great programmers away from programming. We have all those coding schools and we promote coding to everyone, but then we turn them away with OOP and make them think they’re bad coders when they can’t learn it. Yet, some people create amazing apps without OOP, have millions of users, and laugh at programmers who create complex and slow OOP and talk about how great object oriented programmers they are.
I still admire some OOP developers and I understand that some of the best developers out there could not live without OOP, but at the same time I learned that knowing OOP could also mean you’re a mediocre programmer who needs OOP to accomplish tasks that others don’t need OOP for.
If you like to see more reasoning of why OOP is bad, or can be bad, here are a few additional articles, discussions and videos on this topic:
Today, when writing my app, I am commenting it to the max, sometimes adding several comments to one line of code, just to make sure everything is super-clear to myself and others who may be accessing my code in the future. And I believe this can be more helpful than OOP. I also don’t mind if our team later rewrites my code as OOP, as long as I can continue maintaining it using procedural coding and they’ll continue porting my code to their pretty object oriented structures. I’m even curious to see if they’ll be happy doing this, or will give up, or will admit “to hell with OOP”.
UPDATE: A week later I discovered the power of OOP, fell in love with it, and now feel that OOP can be awesome.