I'm about to blow your mind, because you've probably never heard someone say this in all of your indoctrination, erh, ahem, I mean training. Object Oriented Programming is wrong.
The fundamental tennets of Object Oriented design methodology are fallacious. The promise of OOP is that anthropomorphizing data will make it easier for programmers to grasp the data interrelations and interactions, but it just muddies the water for how that data is processed. The class does not exist. It really is just a bag of data--your CDog instance is not a dog, it's electrical signals that represent numbers that represent data that represent a dog--and to treat it otherwise is to peddle in lies.
OOP has done nothing to decrease the complexity of application development, nor has it led to more successful projects (success measured in terms of coming in on-budget). And if you look at the OOP advocated by such ecosystems as Java and Struts, you'll even see a massive increase in complexity.
In any enterprise scenario, the most important thing is data. An enterprise application is nothing without a solid database, and the database will live on long past the application itself. That's the fallacy of N-Tier and MVC architectures: that the database is somehow an integral part of the application. How many times have you worked on new intranet applications that were connecting to and manipulating old databases, be them ancient mainframe systems or over-leveraged MS Access debacles? We'll be writing programs in C# 7.0 before we completely migrate off of dBase II. That's why COBOL applications still exist, the data storage was integrated into the programming language. And in an ever more regulated business environment, our requirements for data are only going to increase exponentially.
But what changes constantly and dramatically is how we want to see that data. That is our application. The means by which we manipulate data are absolutely decoupled from the data itself. In 20 years time, you're not going to want to know how report XYZ was calculated (in some part because it was probably wrong), mostly because your business needs are completely different and that report just doesn't make sense anymore.
By using OOP, you're marrying your data and your behaviors, by its very definition, and then trying to hide your data. It's like playing 20 questions with your business. When some new business analyst comes along, trying to make a name for himself in the company, and declares that System XYZ that has been running perfectly well for the last decade needs to be rewritten "to bring it up to industry best practices", in an OO scenario you're in the old cliche of "throwing out the baby with the bathwater." This is especially true if you've used an ORM system that lets the application drive the database design.
This is probably why there aren't very many jobs for Lisp and other functional language programmers: because their languages were pretty much right the first time so there is no pressure to "upgrade" and their applications just work the first time because they know the difference between data and how we manipulate the data. In functional programming languages, EVERYTHING is understood to be just bags of data. In Lisp and Scheme, you pass around lists to all of your functions, lists that don't advertise particularly well what are in them. That's because, for the most part, it doesn't matter. You don't want your application to know very much about your data. You want to segregate those parts of the application that do know about the data to very restricted and limited areas. The more generic the bulk of the code, the more reusable it is.
Which brings me to yet another fallacy of OOP: code reuse. When was the last time you reused a class you wrote yourself? I bet you have a "Utility" class somewhere that's a bag of static methods, we all do, because OOP doesn't account for the fact that functionality exists separate from data. That doesn't count, that's not a real class. I'm talking about BusinessEntityWidgetX implementing GodAwfulInterfaceY. When was the last time you reused either across applications?
So OOP, you promised the world, and you never delivered. Then you built a system of indoctrination around yourself (university computer science programs) to protect yourself from criticism. Congratulations, you've achieved the status of religion.
4 comments:
Someday I'll be smart enough to agree with this post.
Strict OOP should really be left to the companies that develop frameworks and libraries that developers consume because its a language/patterns we all understand. But guess what ... those don't have databases attached to them with users waiting for GB/TBs of data to be processed.
... and I am more fond of "Util", Sean.
What about applications that don't have a database? Sure, OO kinda sucks when you're trying to build on top of something that is by its vary definition blobs of barely related data.
OO works best when the data exists merely to support the behavior provided by classes. I've re-used OO stuff quite a bit. But there's a few things people need to realize:
- The re-use isn't often at the class level. It's at the assembly/module/dll level.
- Classes in current languages shouldn't represent things. CDog is dumb. A parser is better; a logging target is better. An organized bit of code to do one thing, not all the modelling of some real world object.
- Encapsulation applies to more than just keeping things private. If your class is tied to some database schema, it's not encapsulated. If it's bound to some vagaries of business rules, it's not encapsulated.
Sure, OO has promised too much, delivered too little, and is pretty much over-rated by everyone. But to say it's not easier for programmers to grasp is naive. To ignore the domains where it does do well, or not evaluate the style on merit over zeal is foolhardy.
@Sean
I think I'm going to run into the same problem as you with formulating a response (http://bit.ly/m3BatC), so I'm going to try to keep it as brief as I can...
What strikes me about your blog post (a very interesting read btw) is how much it harkens back to a different approach to programming, which legitimizes the LISP and COBOL references. The evolution of development methodologies has gone from process-oriented (pre-70s) to data-oriented (70s) to object-oriented (90s). Each of these has supplanted the other based on the solution to the prior ones weakness (or supposed weakness lets say).
Treating an application as the interconnection of several business processes obviously ignores the ramifications of data changes. (ISAM/VSAM) Treating it as the graphical representation of the relationships of your data ignores the ramifications of entity-related behavior changes. (Situations where a business process isn't uniform across all customers, though the data is similar) Treating it as the representation of the interaction of objects representing both data and behavior adds additional complexity to the application by introducing additional code to abstract the specifics of business processes into discrete components that also manage the state of related data. It carries the ramifications of adding complexity to a seemingly simple process.
All of the approaches have their pros and cons, and to me are all valid approaches. I have certainly seen the pitfall of trying to object-orient a console-based program simply for the effect of making it object-oriented, and feeling cheated. However, I have also been burned by wiring data to processes and having to migrate changes across multiple processes when data needs to change. In the end though, you do find that there are certain scenarios that lend themselves better to one approach over another, and that is where I feel the real value of object-orientation is.
OOP provides us as humans the ability to more closely map what we observe in reality to components in software. As with all abstractions in computer science, this comes with its own leakiness, including things such as performance overhead and perhaps even a bloated codebase that becomes increasingly more difficult to work with due to class explosion. We have to weigh the good and the bad when making a choice and go with what makes the most sense for the task at hand.
Ultimately, I feel it is our responsibility as developers to use our innate sense of reasoning when presented with "best practices" and decipher the value from the fluff. Those who blindly accept anything they are indoctrinated with will be nothing more than cash cattle for the technology behemoths. While I cannot go to the extreme with you and say OOP is "doing it all wrong", I can also say that it is not the right choice for everything, and that we need to not look at every problem as a nail and OOP as the hammer.
Post a Comment