Ask HN: can you summarize OO for me in 64 words or less?
I've only been writing code for so long, while I grew up designing web-sites, it really doesn't count; so, as of now, I've been invested in programming for more than four years but have never had the courage or foresight to write something in OO. However, for the past couple weeks I've been pouring myself into the OO textbooks, yet I still don't feel reassured in it's value. So, as of today I can speak OO, since I know all the jargon, but I still can't muster up the courage to write an application that seems practical to me, which is where my problem lies. I'm also no software-engineer, but I've come to face the facts that my vision of building tools/programs/output is flat; so please, inspire me with your wisdom from 30,000 feet above, metaphors, philosophy, and expression by comparison is welcome.
EDIT: I guess the origin of my writers block in doing something in OO is that I don't really feel like I'm handling real data. I feel like I'm defining and declaring spaces as I see fit, thus leading me down the path of this pseudo/pretend file-system while ignoring the platform I'm really working on. Please prove me wrong.
75 comments
[ 3.9 ms ] story [ 52.4 ms ] threadHow else would you write software with modular and re-usable components?
But seriously, if you had to write software that abstracts complexity (good), has modular components (good) and let's you attack specific problems one at a time, how would you do it? If you don't think these are worthwhile tenets of software engineering, what are, in your opinion?
If you are curious, look at abstract data types and polymorphism in SML/OCaml and Haskell. Also, look at Haskell's type classes, and look at SML/OCaml's module system.
Here's a paper you can read: http://www.cs.utexas.edu/~wcook/papers/OOPvsADT/CookOOPvsADT...
The answer to your question hinges mainly on how you define components. In the Erlang language for example: It is completely functional but threads actually become somewhat stateful and ultimately end up recreating some similar scenarios for OOP programmers. On top of that, functions themselves showcase an even higher amount of reusability at times especially in functional languages because of the prevalence of lists of things and tuples. This prevents an over abundance of duplicate implementations of the same thing that, even though their signatures are identical (or nearly so) can't interoperate because they haven't been specified as exactly the same. So language wide consistency is a big plus for some functional languages.
Having said that no one tool is a golden hammer. OOP and Functional programming are just tools and there are others out there. Some not even based on Von Neumann architectures that are even more flexible than the ones we, Von Neumann proggies, are (think data flow architectures for example).
Erlang is a well thought out compromise between tying your hands by restricting side effects (the monad approach) and allowing a wide audience of people to be quickly productive.
[1]: Changing the temperature of the environment can be considered a side effect thereby rendering the 100% functional language 99.999% functional.
Clearly you're inexperienced with golden hammer methodology, which provides both a mightier paradigm and a pleasantly horned helmet.
Hah! However you want!
The first few chapters of Paul Graham's `On Lisp' does a great job covering closures, which can provide elegant encapsulation. But even in Java or C++, objects aren't the only modular or reusable components - consider packages or name spaces, for example. Data types such as streams, arrays, and trees don't have to be classes, either - take a look at Haskell's data types.
^ 64 words.
edit: I assumed that the vast majority of languages typically used in web development incorporated some OO features. I'm interested in what is familiar to you; perhaps that will help people describe something that means something to you.
Your question is sort of odd.
OO property 2: You've got a cookie cutter and dough. The Cookie Cutter is the constructor, it makes a object the shape of the cookie cutter insides. It looks like the shape of the cookie cutter, it smells like that shape, it _is_ that shape; but it's only really a copy of that. Which is why people have issues with "equals." Equals can refer either to having the same value, or actually being the same object.
There are other really nice analogies (is-a vs has-a and children vs people), but I hope that my analogies make sense to y'all!
EDIT: the above is 181 words, sorry :-(
Take a real world model and simulate it with some OO code in your favorite language.
For instance, model an elevator system in a large apartment complex. Model the buttons, the elevators, the call buttons, the system the decides what elevator goes to which floor, etc. Those are all objects interacting with each other in some form.
You can't hardly screw up. Mastering OO takes many years, so just get out there and starting hacking around.
BTW, you can read all you want about driving a car, but until you sit down in the driver's seat, it isn't going to "click".
Bonus analogy:
The web itself is object-oriented. You ask a server to return a resource for a given URL; what server it is (Apache; IIS) and how the content is generated (static page; CGI; PHP) is unnecessary for the conversation.
O.O is useful to you because it makes it easier to understand your code, especially if your code base becomes very large. You can look at your code object by object rather than line by line.
O.O is useful for group projects because each member can code an object and the algorithms behind its methods individually. It also makes it easier to swap different functionality in and out.
Finally, O.O also promotes good coding practices, like reusing existing code and writing documentation. It also makes you think about your code's structure, which is crucial to keeping your code maintainable, upgradeable, readable, and reusable.
For me, writing good O.O code is a something that I learned after writing a lot of bad O.O code. So there's no reason to delay - write it and you'll see.
State and behaviour are deeply intertwingled, and object orientation seeks to make programming easier by acknowledging that fact.
Put simply: an object is something with state and behaviour, and an object-oriented programming system is one that makes working with objects easy.
Two ways they do this are information hiding (so you can consider an object a black box and not care about its inner workings) and inheritance (when two objects are similar, you only need to specify the differences between them).
Object-orientation is fundamentally just a way of organising programs.
In most non-OO programming, you've got a bunch of data, and a bunch of procedures that can operate on the data. The two are defined and considered somewhat separately, though they must fit together.
In OOP, a kind of datum and the operations on it are instead designed, defined and used together, as essentially linked.
"Programming by making things that can be interacted with in different ways"
If there isn't an inherent ownership and hierarchy of data and data properties, OO isn't at all necessary. When the structure is well-defined though, which is in many cases, it is the most intuitive abstraction.
Each object wraps up a program. The program's global variables become variables of the object. The program's functions become functions of the object. The public functions are the interface of the object (an interface is the part of a module that interacts with other modules, like the surface of an object). So basically, you have the inside of the object, and the outside (surface).
Think of it as support for the modules that you already wanted, that seem to be naturally present in the problem, or in how you naturally want to divide it up and think about it. That is, use OO to support your conception, instead of a priestly template to mold yourself into. Tools are good slaves, poor masters. If you follow your conception, you will make mistakes - but those mistakes will belong to you, and so you will learn from them.
Using objects for modularity does not work well for every case (e.g. I think parsing works better in the old-fashioned style).
OO is nothing special. There's no wonderful mysterious secret. It doesn't even have a precise definition that everyone agrees on. It's just a tool. Inheritance and polymorphism are grossly overrated, but presented as a quasi-religious AI solution-to-everything - but are useful in some cases (e.g. great for windows/GUIs). There's also a danger of having overly theoretical modules - the "spaces" you mention. Be problem-driven. What does the problem need?
I wrestled with this one in school for a while, because the name is so screwy. What is an object? It's a blob of code. It's a walled off place in your computer's RAM that has variables and functions. It's just a bit of reusable code.
Why is that special? If you've spent your programming life copying and pasting code in a text editor, it's probably not going to be readily apparent. It's pretty easy to reuse code without having to jump through OOP hoops.
In OOP, those reusable bits of code aren't copied and pasted, in the text editor, however. They're reused automatically in memory. When programming in an OOP style, you create one blob of code (an object), and then without touching the original, you can use the object and use it's methods and variables.
You can modify or extend the object, and you're never changing the original object.
For instance, in Ruby. Everything is an object. Even integers are objects and strings are objects. That is, every time I use the integer "5" in my code, I have all the methods from the Integer class available at my finger tips.
So, I can do something like this:
Or, I can use the "times" method from the Integer class, to create a loop: Why can Ruby do this? Because all integers are a type of object that has the .next() and the .times() method that we can use every time we use an integer.The same goes for strings. In Ruby, every string is automatically given all the methods from Ruby's String class for free. So, you can do stuff like this:
and Every string that you use in Ruby has all the String class methods available to the programmer, because in Ruby, every string is an object.There are lots of other things that you can do with OOP, this is just a taste of what Ruby does. I think the key to learning OOP is to learn it in a language that uses it very elegantly like Ruby, or even Python. If you're trying to learn OOP in PHP or Perl or Java, you're in for a rather difficult time, because there's so much other stuff that gets in your way.
But, if you learn OOP in a langauge that uses is really well, you can isolate some of the OOP concepts, and you can go back and use them in your language of choice if and when you need to.
OOP certainly isn't the be all end all of programming paradigms, but it's well worth your while to learn if you're going to be writing code for a living. It's one way to reuse code. It's certainly not the only way.
Going much deeper gets controversial; there are many, many elaborations on that theme, each of which you can find a language that implements it and a language community that considers it anathema.
I have sometimes thought the same thing. There are ample explanations of the use of OOP put in terms of stuff like, poodle inherits from dog, which inherits from mammal etc. or a car could be represented as a series of objects interacting with each other, the engine, gear box etc. This is all perfectly fine and super easy to visualise. But the stumbling block for me is sometimes when I try to turn these ideas to something that's actually useful. Abstact concepts that indeed do not always have a neat corelation in the real world.
If anyone has some tips on how one can begin to develop a clearer method for modeling more abstract concepts in OO, I'd love to hear them.
Most articles carry some example to go with the concept being explained.
Regarding inheritance, I once had a conversation with a "application architect" who advised staying away from inheritance until you fully grok it, because it's easy to paint yourself into a corner with it (he then disappeared before I could question him further). The only issues I could think of at the time was stuff like say you have a bird class which contains a "fly" method, with duck and emu child classes (now I'm using the dodgy animal examples :P), the duck and most other birds should be able to fly, but the emu and some others should not. What is the better practice way of dealing with this issue? And what other adverse issues can arise when using inheritance?
It has been recommended to me in the past that when it comes to systems that require more abstract objects, this is where researching design patterns would assist. However, pretty much all the design pattern literature I can find is not directly related to my current language of choice, Ruby. I can find lots of stuff talking about design patterns in Java and whatever else, which still provides some utility, but is there any books/articles that anyone can recommend on design patterns etc. using Ruby?
"All of these objects do very similar things. I don't want to have to write these functions over an over again if they're so similar..." and inheritance was born.
Most OO concepts are about writing and seeing less code. I think the best way to grasp OO is to ban ctrl+c for anything longer than 2 lines. It really forces you to think about structure and code reusability, which is what OO is all about.
Not all objects are alike. Smalltalk is "pure"; Python and Ruby mostly "just work"; C++ is very complicated.
No programming paradigm can save you from under-specification. You need a very good description of your desired behavior before you start coding.
Smalltalk is a great start. If you want to read more, this poorly named book is by far the best I've read on the topic: http://www.amazon.com/Software-Development-Principles-Patter...
[1] http://en.wikipedia.org/wiki/Programming_in_the_large
abstraction, hierarchy, modularity, encapsulation
manage complexity reduces resistance to change over time
design patterns give best practice advise