Allen Wirfs-Brock gave the following defense of OOP a few days ago in a series of six posts on Twitter:
A young developer approached me after a conf talk and said, “You must feel really bad about the failure of object-oriented programming.” I was confused. I said, “What do you mean that object-orient programming was a failure. Why do you think that?”
He said, “OOP was supposed to fix all of our software engineering problems and it clearly hasn’t. Building software today is just as hard as it was before OOP. came along.”
“Have you ever look at the programs we were building in the early 1980s? At how limited their functionality and UIs were? OOP has been an incredible success. It enabled us to manage complexity as we grew from 100KB applications to today’s 100MB applications.”
Of course OOP hasn’t solved all software engineering problems. Neither has anything else. But OOP has been enormously successful in allowing ordinary programmers to write much larger applications. It has become so pervasive that few programmers consciously think about it; it’s simply how you write software.
I’ve written several posts poking fun at the excesses of OOP and expressing moderate enthusiasm for functional programming, but I appreciate OOP. I believe functional programming will influence object oriented programming, but not replace it.
32 thoughts on “The success of OOP”
I completely agree. Having driven the conversion of a major OSS project from pure procedural to OOP code over the last few years, it’s not a silver bullet but it definitely makes managing larger code bases and larger teams far easier. You have to not abuse it, of course, but that’s true of everything.
Many FP principles are just restatements of OOP principles in a different way. These days, I’m strongly advocating Functional-esque OOP: Separating service objects (functions) from data objects (structs), making the latter immutable where possible (and the service objects, always), using map, reduce, fold, etc. where possible at the micro-level, and so on.
All of these different programming paradigms are hard for many people to grasp, but they really are all valuable in their own right, for the right things. And when you get down to it all say the same thing: Maintainable code comes from divide and conquer, separation of concerns, and otherwise breaking a problem apart. The rest is just syntax and methodologies for breaking a problem apart.
>> Many FP principles are just restatements of OOP principles in a different way
I think you’ll find FP ie Lisp came before OOP.
>> I’m strongly advocating Functional-esque OOP
I am reminded of :-)
Disclaimer: I’ve been an OO developer for 20+ years. Sick of implementing of FP ideas in OO hence now a fully fledged Clojure convert.
Larry, I agree with you about separating functions (service methods) from data objects (structs, maps, what have you), but the purists will call that an anemic class and an anti-pattern.
Purists are very useful until they aren’t. :-) It’s extremely tempting to put business logic onto domain data objects. Sometimes it makes sense, and it’s fine. But one of the most common refactorings I find myself doing is moving such logic off of a domain data object into a service because it’s more maintainable, it avoids a service dependency on an object that needs to be serialized, it’s more testable, or some similar reason. I almost want to see a language with a syntactic distinction between service objects and data objects/structs-with-utility methods to help drive that home. (Such a language may exist; I’ve just not used it.)
bowlocks: If you really want to be pedantic about it, FP traces its origins to Church in the 1930s, as do turing machines. OOP still comes out of the procedural/turing mindset. And the term FP, as far as I’m aware, didn’t exist until 1977 although LISP does predate it. LISP is not a purely functional language, though. In either case, the point being that “good” practices in a purely FP world and in an OOP world are not all that different; they’re just expressed differently.
2 major caveats:
First, OOP is a very vague term, whose meaning shifts drastically over time and across communities. I’m willing to believe OOP is a success, but the truth is, I don’t even know what you are talking about.
Second, to what extent the recent (last few decades) progress on our ability to make software can actually be attributed to OOP? there are more mundane reasons, such as the unbelievable hardware progress (we have more MIPS and megabytes than sci-fi authors even dreamt of), better tools (debuggers, profilers, IDEs…), or practices (such as automated tests). Those alone make many things possible. The actual contribution of the various flavours of OOP is therefore unclear.
I almost want to see a language with a syntactic distinction between service objects and data objects/structs-with-utility methods to help drive that home. (Such a language may exist; I’ve just not used it.)
I think Haskell fits that description perfectly, if you think of datatypes as data objects and typeclasses as service objects.
I completely agree with you.
However I must add that I feel best in a multi paradigm environmentt. Throw in some OOP, throw in some functional style and, yes, sometimes I even throw in some old school, structured, procedural programming. I think we are lucky to have this wealth of tools at our disposal. After all, how many programs are written in Smalltalk? Or in Haskell? Thanks c++. Thanks Java. Thanks Python. (I’m sure there are more of those)
Larry: I was just responding to your statement that “Many FP principles are just restatements of OOP principles” which I interpreted as an ordering of what came first. In my day-to-day “Corporate Java” development I try to foster the use of immutable POJOs which just contain data – and various “Func” objects which only encapsulate business logic. So where you say “they’re just expressed differently.” that may have an element of truth but in OOP (Java in particular) FP principles have to be part of your class design whereas in FP languages such as Clojure, the same principles are idiomatic.
OOP may be good but C++ is certainly not, though it is the language which established and popularized OOP!
By declaring itself a super set of C, C++ has proved to be an evil parasitic creeper coiling itself around C and stifling all enhancement in C.
Today, most languages boast a far far better version of ‘switch’. Even a simple but heavily used construct has not been improved.
But for C++ (hogging all enhancements and improvements (???)) we could have hoped to see – safe/ dynamic arrays, strings and containers and also libraries (out rivaling the kind of libraries that have made Java/ J2EE so popular) as part of standard C. After all C is the language which is synonymous with utilities like Grep, Lex, Yacc and … and … Languages like Perl and PHP and even the JVM (on many platforms) are written in C.
Tie a man’s legs and attach some heavy stones and then run against him – that’s not a race!
Free C from the clutches of C++. (C++ can continue to tread its path of purity, even if unintuitive, at its own snail pace.)
And books on C++ make it a routine to deride C style pointers and the use of ‘void *’. What about the VTable – is the content homogeneous i.e. do all the function pointers have identical signature – parameters and return type? Trying to influence students that C is OK for printing “Hello World!” but not more than that!
All this is affecting the C programming community – lack of language improvements and losing young minds. I am not being fanatical about C but as (late) Ritchie put it ‘C wears well as your experience with it grows’. I can vouch for that from my own experience.
The fact that EcmaScript 6 has classes whereas the older versions don’t, says something about OOP. To me, OOP is a success.
I have to disagree.
Half of my career was spent writing massive applications in OOP languages, such as MMORPG games or major business applications. In my experience, if one carefully tracks where its time is spent while developing in OOP, it is soon evident that as application grows in size and requirements keep on changing, more and more time is devoted to restructuring rather than problem solving, such as refactoring two or more domains of code to pass data from one domain into another.
This is for me the primary fail of OOP, because this data already *does* exist in memory; the reason it is invisible at the place where I need it is because of encapsulation, the main OOP pillar. Encapsulation itself is achieved through code structure without well-defined problem solution, because problem itself keeps on changing.
OOP would work flawlessly in situations where problem is defined up front and its set in stone.
Other half of my career was spent writing imperative code (just C and “functional C++”) and while there are some other problems using this paradigm – most of questions that an OOP architect has to ask himself at the beginning and during the development are completely non-existent here. Paradigm itself doesn’t allow for such encapsulations so that data travels (= is needlessly copied) through multiple modules.
I don’t have quite enough experience writing pure functional code yet, but imperative/functional paradigm so far (6 years) seems to solve nearly all problems I ever had with OOP. I don’t think its the silver bullet, but it is by far most forgiving towards change.
Also, apropos application size – I think OOP has some effect on this, but not in the way Mr. Cook would propose. Applications grew in size because computing became mainstream. I would suggest that OOP’s effect is at the fact that it is easily understood and learned by many people, whereas clean functional paradigm requires somewhat more intimate connection with applicative maths. If one doesn’t know how to use math to solve a problem, one will have many problems expressing its problem (and solution) using FP.
I have been programming for over 30 years and have used just about every programming paradigm and language available and still actively developing.
As far as writing larger applications, that’s just not the case, in fact using OOP (C++,Java, C# etc) have introduced unneeded complexity making it harder to to manage and debug. One of the biggest issues now is just the sheer volume of unused, near duplicated, or overly abstracted code.
I would not call C++, Java, c# OOP but Object based, as OO is pure message passing, Dr Alan Kay who coined the term OO, “OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them.”
Witness some of the failures of projects moving to OOP from mainframe, c, cobol, smalltalk, lisp eg: IRS, Air Tours, Air Traffic Control, and many more. Not to mention many embedded failures after moving to JAVA from C. And as far as the functionality, it was invariable decreased because of the switch.
The Current Software Model is over! No any kind of OOP in the future! I talk about the transition to Individual paradigm (the Informational Individual!!!). In fact, this means to know the problem to solve, rather than programming. My web site give you an introduction in the future kind of thinking about information. I’m 80% ready with the new software — Universal Software Model!
The success of OOP is mainly due to the fact that for most people it is far simpler to reason in terms of objects and the operations that can be performed upon an object. This is also why finite state machines are successful, where an action upon an object in a defined state have a defined outcome.
Functional Programming and OOP are not incompatible despite what the 1000s of flame wars on the net will tell you. FP is one tool in the toolkit in the exact same manner as OOP is. If a operation (or the concept of the operation) is independent from an object on which it is performed then FP is probably the answer. Generics, OOP and FP can and often should all be applied in certain circumstances.
Languages which only allow a sub-set of these frustrate me. ECMA doesn’t let me properly encapsulate data, or even functionality. Java’s nascent support for functional paradigms has been a great addition, but the generics are still a long way short of where they could be. C++ obviously lets me use all three but template programming (when I last used it at least) is still hit and miss.
If you are a “OO programmer” or a “functional programmer” or an “imperative programmer”, well I think you are probably just limiting yourself, and in some cases I’m sure you are using the wrong tool for the job. It’s like a carpenter who only uses a hammer.
As others have stated, OOP isn’t just one thing. OOP using the SOLID principles looks very different than OOP using a top-down approach. And there’s combinations of SOLID and top-down such as IoC containers that allow top-down classes to consume SOLID classes.
It bothers me when people claim things like “OOP was supposed to fix all of our software engineering problems and it clearly hasn’t” because no one ever makes those claims. Someone is just trying to strengthen a different view point by contrasting it against a mythical extreme. It’s harder to argue against shades of gray, but that’s reality.
> But OOP has been enormously successful in allowing ordinary
> programmers to write much larger applications.
But what if OOP has done more harm than good? If OOP was not popularised then it is entirely possible that ordinary programmers would be writing even larger applications under some other paradigm.
OO would not have become so dominant if businesses didn’t see real benefits.
> OO would not have become so dominant if businesses didn’t see real benefits.
Short term benefits perhaps?
I like FP because I find it enjoyable. I find it easier to understand, at least when it is kept simple, it can get really complex. I find OO complex because it does starting looking like “spaghetti” code after a while which makes it harder to reason about. over on fsharpforfunorprofit he shows a couple diagrams of C# vs F# and there dependencies, F# is linear, C# is all over the place.
Having said that. I don’t think there is any reason to toss out one or the other. I think it is a thing more of preference. It would be nice to have some hard data. Of what I’ve seen so far it appears that FP could be “better” but I’m not entirely convinced yet.
> OO would not have become so dominant if businesses didn’t see real benefits.
OOP only became popular because of myth that it would solve all your programming problems, One of these is the Myth of Reuse, which says that OOP makes you more productive because instead of developing your code from scratch, you can just inherit from existing code and extend it. The other is the Myth of Design, which implies that analysis, design and implementation follow seamlessly from one another because it’s objects all the way down.
Pointy haired bosses not having a clue, saw it as business benefits .
The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones.
If you want to see it from the flip side, then articles like this linked below are tremendous. A lengthy, but worthwhile read.
completely disagree. If without OOP, people might have adopted functional programing earlier. I don’t mean Haskell or whatnot academic things. Just plain common sense use of functions, lots functions, in modules and namespaces.
To me, OOP has harmed programing community significantly. Also it is a harm to programing education.
But, ultimately, we need science based evidence. Namely, social science here. As far as i know, few are done in this area, as it is rather academic, comparatively useless and no immediate business benefits.
I read the “expensive disaster” article a while back. I found it half a valid critique, and half fanboi ranting against something not-his-preference. :-) Of note, though, is that it was comparing OOP to pure FP. I don’t know anyone still defending traditional procedural code anymore, which is for the best.
Regarding it being “a thing more of preference”, there are certainly many similarities; see this presentation I given on Functional Programming in PHP:
But it’s also a question of the type of software you’re building, and the scale. Some things lend themselves better to OOP, others better to FP. See also, Norris Numbers:
I’ll defend traditional procedural code in HPC circles.
An interesting difference between OO thinking and FP thinking is the way these paradigms approach designing an architecture. OO is more of a top-down approach: Think about your problem, model domain object, implement them. For FP, a bottom-up approach comes more naturally. Think about your problem, inputs, results and implement a function that maps inputs to outputs. on the way, solve the subproblems you encounter using the same approach. FP feels more agile here to me.
The problem with OO that I encounter a lot is, that it is quite easy to put the logic into the wrong spots. At first the idea to model all worldly entities into classes is really appealing, but too soon you may see that not every object in the physical world makes a good class in your code. You might argue that this is a problem with the programmer who should have thought more careful about which objects and classes to model/write. The OO paradigm does not have any clear advice on how to do this. The Software design patterns are a clear symptom, that even experienced programmers struggle with this.
With logic distributed over classes, writing unit tests is way more difficult than in FP where you mostly prepare some input data, and check that the function evaluates to the expected result.
Object oriented programming should be presented as a way of thinking really, not just a concept of software developing. I belive the way its emphasized makes a big difference in the way it will be used.
Right now is presented as a data structure but it is more than that. If it were that simple we would have used it from the moment programming was born.
I can’t really imagine someone having the nerve (or misunderstanding of OOP’s profound impact) to make a comment like that. I can honestly say that if I hadn’t learned programming through OOP techniques then I would have either been in a different field, or I’d be a pretty lousy programmer. Sure, there are other ways to solve the same problems, but OOP solutions make the most sense to me. Just my two cents.
> I can’t really imagine someone having the nerve (or
> misunderstanding of OOP’s profound impact) to make
> a comment like that.
Scott – which comment was that in response to?
My personal experience is that the more someone understands OOP, the more likely they are to criticise it. A lower barrier to entry is great to get novices doing *something*, but most of OOP is broken and does not scale.
BTW, I’m not convinced that if you learned programming through some paradigm other than OOP that you’d not have stuck with it. Of course, this can’t be proved and so we can choose to ignore both of our opinions on the matter.
OOP makes most sense to everybody because its very easy to map concepts into objects and then, subsequently, express them using object-oriented language constructs (whether its a prototyping lang or class lang).
This is why OOP is so successful – programming is all of the sudden easy.
Hint, its not.
As soon as your problem domain starts including something that can’t be solved by writing some glue around a massive application/library stack (for example, realtime performance on modest hardware, no-crash policy, bug-free software, etc), or even when your application reaches certain size – OOP is literally a hindrance that doesn’t exist in other paradigms. This is not due to programming skills; it is due to how you’re expressing the problem.
Take Haskell as an example – its language syntax is so vastly different from imperative/OOP programming that you simply can’t express buggy code. For problem domains listed above, being able to write massive applications without keeping a gigantic state vector in your head is a blessing.
Modern OOP has nothing to do with OOP how it was taught. For example, modern OOP is dividing objects into ‘data objects’ and ‘algorithm objects’, which violates basic OOP principle that algorithm has to sit next to data with which it operates.
When you gather most of these best practices together, you see very quickly that modern OOP is just flawed procedural-imperative programming in disguise.
My comment was actually in response to the quote within the article, not a comment on the article. I didn’t mean to defend OOP as the paradigm to rule them all, just that it’s success or failure shouldn’t be determined by it’s ability to solve all of our problems (as the “young developer” from the quote seemed to imply). Of course there is no perfect paradigm out there, but I do think each has its place in certain applications/problem spaces – OOP included.
OO was something when various OO schools defined it. It was discontinuous, so adoption was slow. But, all of those OO schools failed. MS rewrote their API w/ GETs and PUTs, the idealism went out the window, but OO became continuous and subsequently got adopted rapidly. Yes, OO thinkers, the strict OO people think it failed. Then came lattices and design patterns. We’ve moved well beyond OO.