Hacker News new | ask | show | jobs
by qwertyuiop924 3572 days ago
Here's the OOP model:

A program can be modelled as a set of communicating black-box objects, with their own state.

The idea is to separate concerns, abstracting away implementation behind well-defined interfaces, which can in turn be implemented by other objects to cleanly replace parts of the application.

The rest of OO is pretty much just understanding Design Patterns (a set of names for common interactions between objects, and methods for setting these interactions up), grokking inheritance, and the difference between inheritance and composition, and grasping how to design a good OO system (how thickly to layer your classes, how much abstraction and what sorts, etc.)

The best languages for learning OO are Ruby and Smalltalk.

6 comments

This is actually a really good summary. I also agree on learning Smalltalk to learn OOP since it has a really easy syntax, you can deep dive into implementation details if you want to easily and it enforces some best practices like setter and getter instead of giving you the ability to just declare members public. I learned Java in University and switched soon to Objective-C and it took me a while to see reasons behind getters and setters especially since I worked only in small teams on short living projects at that time. Also s Smalltalk is purely OOP so you won't get distracted by numbers and bools behaving differently. And finally it gets you to think in data structures thanks to the collection methods.
Yup.

Getters and setters only really work in programming languages with good metaprogramming support. In Java and Objective-C, they're ungainly and awkward. In Smalltalk and Ruby, they just kind of happen.

I agree that learning Smalltalk is the best way to learn OOP. But you should be careful with design patterns, design patterns are not a tool that you just use, they arise naturally in an OO model, and you should know them well to recognize them. Besides, several of the design patterns from the GoF are not necessary in a language with closures.

I strongly recommend three books:

Smalltalk, Objects, and Design - by Chamond Liu

Object Thinking, by David West

Object Design: Roles, Responsibilities, and Collaborations by Rebecca Wirfs-Brock

No. Design patterns are just idioms, ways of accomplishing something. They aren't enshrined in any way by OO.

As for the idea of a set of common patterns that can be reused in a variety of situations, yes, that's a natural consequence of OO. But that's a natural consequence of any paradigm. OO's just had better marketing and GoF gave them a name.

In addition to what you said, OO to me is all about things sending messages back and forth between black boxes, such that the message contains everything the recipient needs to either do its job or find the information needs to do its job. Alan Kay (since you brought up Smalltalk) has said that he wishes he called it Message Oriented Programming instead, because people took the wrong message out of the name. In this line, Erlang and Smalltalk, and to a slightly lesser extent Objective-C more fit in with this. But you can code that way in Java or whatever, if you just think about the message between entities being an actual first order thing in your system.
Yes. Java's main failings were its strong typing (forcing interfaces to be a needlessly awkward solution), and an emphasis on inheritance, creating deeply nested hierarchies, and leading people to use Hungarian Notation, creating even more awkward naming.

In any case, you can write OO in any language. Heck, if you look into the history, Scheme, A multiparadigm language in the Lisp family typically associated with FP, was actually intended to be something approximating OO (it was designed to implement Carl Hewitt's Actor Model, so as to help Sussman and Steele understand it better. They subsequently realized that their code for creating actors and sending messages was identical to their code for instantiating and calling functions, leading them to generalize and only include lambda in the language, concluding that actors and functions were one and the same. Hewitt did not approve).

An alternative route would be to study programming paradigms from Concepts, Techniques, and Models of Computer Programming [0].

One of the authors is teaching a two-part MOOC on edx over the material [1] (how much of it, I don't know).

[0] https://mitpress.mit.edu/books/concepts-techniques-and-model...

[1] https://www.edx.org/course/paradigms-computer-programming-lo...!

I think qwerty's explanation is a little bit too high level. It feels to me more like a definition that people that already understand OOP can use to talk about it than a useful definition for a beginner to understand it.

OOP at it's core is about answering the question "Where the fuck do we put our code?"[0].

Imagine it's the long ago and year is of 1 B.O.(before OOP). Your language has primitive types and functions. You maintain a large line of business application. Someone has just invented the apartment building so you are given the task that to make sure your application handles apartment units correctly. You go through and find all of your functions that take parameters like "int streetNumber, string street, int zipcode,string city", and you add apartment number to them getting "int streetNumber, string street, string apartment, int zipcode,string city". Having these 5 parameters that you pass into all the same functions is super painful. It's also error prone to edit.

So you decide there has to be be a better way and decide to create structs. You decide to group these 5 parameters together into struct(which you just invented) called mailingAddress. This is really great because you have organized these 5 parameters into one object, so mailing address is now 1 parameter instead of 5. And if you need to add or change one of these parameters there is only one place to change it. You won't accidentally forget to add apartment to some function because as soon as you add a mailing address parameter it comes with an apartment baked in. But unfortunately you still have to hunt down every function that is scattered around your goliath project to find what functions modify this mailing address. You have an itch that this could be done better. You lock yourself in your closet and go into a deep meditation for 3 days.

You come out decide there is a better way and you create classes. You decide that you'll group all of these functions that modify and interact with mailing address and put them in the same file with your struct and call it a class. This is great because in the future when you want change how the mailing address(which is something that your stake holders cares about which we refer to as the domain) works you know exactly which file to go to.

It really is that simple. 80% of OOP is just making sure you group the right code together in a way that you can find and change the code when a stakeholder asks you to. There is much more advanced OOP foo, and for that I would ironically suggest https://fsharpforfunandprofit.com/series/designing-with-type... which will blow your mind when you're ready.

[0] - yes of course it can be get more complex in terms of typing/ encapsulation/inheritance/polymorphism. [1] - I know this is simplistic because functions are data.

Strong types are by no means necessary to OO.

As for your explantation, that's technically true, but that's a very dangerous way to think about OO. OO is about treating objects as collaborating, independant entities, and if you view objects or classes as just, "a place to put your code," you'll run into trouble when you have to start thinking about objects as, well, objects.

Out of curiosity, why Java is not best language for reading OO? Any reason?
Because Java uses strong typing and largely early binding, which are almost always The Wrong Thing in OO.

Actually, by the Alan Kay definition, Java isn't even really OO at all. It just kind of looks like OO. You can apply OO techniques to it, but it's better to learn real OO than the bastardized version that's taught to Java programmers.