Ask HN: What is the state of the art in OOP?
I used to do a lot of object-oriented programming and found myself reading up a lot on how to do it well.
When C++ was the dominant OOP language there was a very different set of best practices than have emerged since. Some of the newer ideas I know of are BDD, internal DSLs, and the importing of ideas from functional programming.
My question is: is there any consensus on the best way to develop object-oriented software today in the more modern languages such as C#, Ruby, and Python? And what are those practices? For instance, I rather like the idea of stateless objects but how many are actually using that in practice?
Or, is the state of the art to deemphasize the importance of OOP? This might be the case for some Python programmers but would be difficult for Rubyists.
35 comments
[ 3.4 ms ] story [ 89.4 ms ] threadYou mention Python, it allows you to write both OOP and FP code. Functions can invoke methods on objects.
As for "state of the art" I'm learning more from reading open source project code than by reading books. I find that different languages have evolved different styles / patterns.
copy.copy: Who don't you "from copy import copy"?
self.x: It explicitly distuingishes between local variable and field access, which is the Right Thing in my opinion.
I do not understand, what this has to do with OOP at all.
def something(self, ...) # inside a class
or
len(str) # instead of str.len (i know i can do str.__len__)
not very convincing reasons right? to me python has a strong foundation in OO. you want a tacked-on-OO-feeling? try php and/or perl :)
edit: Even though I haven't used it, Newspeak (http://newspeaklanguage.org/) seems really interesting as well. Though I'm not sure if it's still being actively developed. Gilad Bracha's blog (http://gbracha.blogspot.com/search/label/Newspeak) explains a lot of the concepts. I find it especially interesting because like Smalltalk and Lisp it seems to be based on a small set of powerful primitives.
However I do like Prototype based OO (http://en.wikipedia.org/wiki/Prototype-oriented_programming) and especially its implementation in Io (http://www.iolanguage.com)
But I doubt you'll find useful sources for programming style searching for it.
If you are implementing an object-oriented paradigm for your programming language, it's a very recommendable source to discover what can possibly be done with OOP.
How about AOP? (http://en.wikipedia.org/wiki/Aspect-oriented_programming). I think both CLOS & Moose push you more towards this programming style.
* Nicer to write than standard Perl OOP, ie. less boiler plate, quicker prototyping, covers bizarre corner cases, etc
* Moose is pretty much de-factor OO framework for Perl now, ie. big community drives its development and usage.
* Perl6 synergy, ie. Moose heavily inspired by Perl6. Makes it easier when I switch between writing perl5 & perl6 code.
For reasons why I think Moose makes the cut:
* Roles - ala Smalltalk traits. see http://search.cpan.org/dist/Moose/lib/Moose/Manual/Roles.pod
* Types - See http://news.ycombinator.com/item?id=1558882 (and also follow links back from it).
* Method modifiers - See my AOP comment elsewhere
(how many have written mostly smalltalk last year?)
"I always knew that one day Smalltalk would replace Java. I just didn't know it would be called Ruby." – Kent Beck
* People like Robert "Uncle Bob" Martin popularising and extending the ideas of Bertrand Meyer with i.e. SOLID principles, and design ideas focussed on quality and maintainability.
* Domain Driven Design, also in some sense a rehashing of old ideas but combined with some new ones as well.
* Service Orientation and Component Orientation could both be seen as extensions of OO to higher level design and architecture.
Being more of a lisper, I think stateless objects describe problems better suited for functionnal style and pattern matching. Relying on the type system of the implementation is a very unspecified aspect of a language. May be ok though if you know it is fast.
Rubyists still have blocks and closures, bringing in a lot of functional style, almost unnoticed.
The styles are complementary, finding the best one for the problem at hand is the art of program designers.
For _me_ Data Oriented Programming is the future. My data does not need to be intelligent. For that I have my central data processors. As soon as there are no "objects" that need to talk to each other parallelism becomes so hassle free.
The only case I still like OO for is UI programming.
I also find that functional programming is often a much more natural fit for solving a lot of problems than OO is. I find thinking in terms of streams, lists, trees, tables and higher order functions often maps much better to the data being modeled than an object hierarchy does and is often more parallelism, cache and out-of-order processing friendly than OO is. I don't really feel that OO is very suited to modern processors and certainly not to every problem we are trying to solve.
http://gamesfromwithin.com/data-oriented-design
OO has undoubtedly been extremely overhyped. Unfortunately the backlash is not as hard as it should be, because by now OO is so firmly entrenched in the corporate sector that it will take (at least) one generation to merely flush it out of the fields where it doesn't belong at all.
That said, sometimes OO might be just what you want to finish the job cleanly and on time. [Edit: typos]
Things that are popular and important:
- Refactoring
- Test-driven development
- Closures and first-class functions
- Domain-driven design
Things that are important but not popular:
- Evolutionary design (aka continuous design)
- Refactoring beyond what's built into IDEs
- Domain and business expertise
- Conway's Law; small, close-knit teams; minimizing dependencies on other teams
- Minimizing maintenance costs over initial development costs
Things that are currently popular but likely to lead to pain:
- Domain-specific languages, particularly internal DSLs
- Behavior-driven development, particularly external DSLs like Cucumber
- Storytest-driven development / acceptance test driven development
Here's a brief rationale for each one.
Important and popular:
- Refactoring: Allows you to improve design as you learn.
- TDD: Significantly reduces programmer error.
- Closures + first-class functions: Enables new design abstractions which reduce duplication.
- Domain-driven design: Nothing really new here, but it's a useful way to describe OO design that's finally making an impact on the legions of people who programmed procedurally in an OO language.
Important but not popular:
- Evolutionary design: The only technique I've seen that actually improves code quality over the long term. See also http://martinfowler.com/ieeeSoftware/continuousDesign.pdf (PDF)
- Refactoring beyond what's built into IDEs: Most people I meet don't significantly improve the design of their software when they refactor. Instead, when they need big improvements, they rewrite (and call it "refactoring"). I think that's because they don't really understand refactoring, which involves a series of small, behavior-preserving steps, most of which are not automated by IDEs.
- Domain and business expertise: Provides context for trade-off decisions.
- Conway's Law: I see the most defects and productivity problems at the boundaries between teams. This makes team structure an architectural question as well as a political question. When you have a large system, how do you break it into parts and who works on what? A careless approach results in a lot of cross-team communication, which leads to performance problems and defects.
- Minimizing maintenance costs: Most software spends more time in maintenance than in initial development. See also http://jamesshore.com/Articles/Quality-With-a-Name.html
Popular but long-term pain:
- DSLs: Suffer the same problems that frameworks do, but worse: When your needs diverge from the solution offered, you have to hack in kludgey workarounds. They suffer from leaky abstractions, so when they don't work right, it's time-consuming and difficult to figure out what's wrong. You're locked into their syntax, so switching to an alternate approach is difficult at best and requires a rewrite at worst.
- BDD: Started out as "TDD with different words" and became steadily more obsessed with automated english-language specifications, which adds cost over TDD without adding significant value. The hope that business users will read (let alone write) a BDD specification is a pipe dream in nearly all cases, and programmers are perfectly capable of reading well-written code--which has the additional benefit of being more precise than english. The "fluent" interface many BDD frameworks use suffer all the DSL problems I just mentioned. External DSLs like Cucumber gravitate towards slow and fragile end-to-end tests (see next item) and also don't play well with refactoring tools, which is a maintenance problem.
- Acceptance test-driven development: http://jamesshore.com/Blog/The-Problems-With-Acceptance-Test...
Embrace explicit state with state machines and events.