Ask HN: Any Tips for Understanding OOP?
At this point I can no longer recall how many intermediate programming courses I've completed that teach the basics of classes: inheritance, properties/methods, getters/setters, polymorphism, constructors/destructors, etc. But what I'm finding much harder than learning the syntax is how to actually put these ideas to use in real code, which seems like the real art form in OOP. I've seen a million examples of Cat classes extending the Animal parent class with an overloaded method, and Car classes that have color, weight, and speed properties with Accelerate() and Stop() methods. But this isn't enough to help me employ OO patterns when solving problems with programming. Every time I try to level up my programming skills from "scripter who only writes a bunch of statements, functions, loops and conditions" to "programmer who follows a thoughtful/logical design pattern that other developers can understand and build on top of" I become paralyzed by not knowing how to fit the idea of my program into an object oriented model. As much as I love him, I'm realizing that watching another Derek Banas video isn't what I need right now. Does anyone have some tips for "thinking in objects"? Something that will help this paradigm click and help answer the following questions? I'm not sure how much this matters but I am learning primarily in Python (although I've explored this topic with other languages too).
- How do I decide what parts of my program should be based on classes?
- Is it possible to go OO crazy and needlessly complicate the program? How do I KISS?
- Are there any tools or resources that can help model a program from the onset using an OO design pattern?
- Can I write a serious program without OO or should I resign myself to staying in script kiddie land until I learn it properly?
- Should I look into another paradigm? Is my only other choice to use a functional langauge like F# or Clojure?
10 comments
[ 3.0 ms ] story [ 38.3 ms ] threadI very rarely use inheritance. I can’t remember the last time I added inheritance but I sometimes come across it in code bases. Normally when there are something resembling UI widgets that have a common base.
Instead I use c# interfaces for polymorphism (which basically means working with objects you don’t know what they are, e.g. I have something that behaves like a list, so i can call addItem() )
My first advice is don’t worry - if your code works and is understandable all is good.
My second advice is post your code for code review, or get a mentor or coach to help show you if and how your code could be better with OO
Functional programming avoids the need for OO but comes with its own “what is the best way to do this” type questions to which I give the same advice.
Are the methods that are managing the state of that object apart of that same class or a different one? Or doesn't that matter? When you say "anyone outside" do you mean, for example, another developer who might be using your code as a library? If so, couldn't they just modify your code to work with it however they want irrespective of how you wrote it?
> I very rarely use inheritance. I can’t remember the last time I added inheritance but I sometimes come across it in code bases. Normally when there are something resembling UI widgets that have a common base.
This is helpful to know.
> My first advice is don’t worry - if your code works and is understandable all is good.
Thank you, that is encouraging.
This is like a facade or a shop front. The menu you order from but not the kitchen or the chef.
This means you interact with the class just through the methods.
Sometimes the methods are simple - it can be a get and set method wrapping a state.
Why bother? Why not just make the state public?
Because then other classes start to depend on the inner workings of the class in order to not be broken.
For example suddenly you realise a string has to be valid e.g. it is an email address.
With a getter and setter later on you can add validation to the setter if you wish.
—-
When I said “Anyone outside” this might be misleading. I should say any code outside the class. This is not really for security - as you said if the other developer has the source they can change it and use the changed source. You don’t enforce security with classes.
Rather than security, the purpose of classes is abstraction: the goal of reducing the cognitive load. The load on your brain.
For example most programming languages will provide classes to open a file. You can now work with the file system in an abstract way without writing code that cares about Unix/windows file system differences in your code that is doing something else.
This means someone can write a program to scan your disk for mp3 files and catalog them without knowing the details of the files stem, and in such a way that if in the future the file system classes are updated to handle say NAS your mp3 hunter program still works.
Even better it gets a new feature for free!
But this simulation concept is not particularly well adapted to the world of business and information technology. Business is highly data driven and most business objects are defined as data. The objective of business software is typically to process input data (lots of it) and produce output data. There is little real world evidence to show that this can be done easier, faster or more efficiently using OOP.
In my opinion, unless you're creating a real world simulation of some sort that will exist entirely within computer memory, binding data and code together offers little practical, real advantage. When it comes time to communicate or store business data, the OOP code/data binding actually becomes more of a hinderance.
This is not to say that OOP is not useful. It's no surprise that one of the most popular applications of OOP is building graphical user interfaces --- an on-screen simulation of a paper data form that is built and exists entirely within computer memory.
Applying OOP to problem spaces where it is not well suited often results in slower, more complex, harder to maintain applications. Instead of spaghetti code, OOP programmers all too often tend to create spaghetti objects that obfuscate more than enlighten.
The stranglehood that OOP has over developers has loosened a bit in recent years. In particular, a whole class of newer programming languages (pun intended), e.g. Rust, Go, Nim, Julia, do not pitch themselves as OOP languages, although they all have object-like features.
There was a time when OOP so completely dominated the profession that any programmer who disliked or struggled with OOP was cast as a programming pariah. Thankfully those days have passed.
> Can I write a serious program without OO...
Absolutely! See any program written in a functional only language, or C.
> Should I look into another paradigm?
Eventually... I'm personally a huge fan of Clojure. That said, don't give up on OOP. It's pretty unavoidable in industry.