Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: Any Tips for Understanding OOP?
6 points by replwoacause 10 days ago | hide | past | favorite | 10 comments
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?

The idea behind OOP is to simulate real world objects. One of the first OOP languages was called Simula.

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.

I'm not sure what business model you're referring to in which it's easier to just ingest data and run analyses... but in customer-facing systems or logistics programs or online reservations software, where lots of users are passing around discreet collections of data pulled from some initial query and expected to parse back into the database after modifications, having strongly typed objects that you expect to be passed around is absolutely critical. E.g. I never worked for Lyft or Uber, but it's hard to imagine any sane way their front ends could be written without objects for routes, vehicles, waypoints, customers, payment sums, etc.

I agree with what you say. However, OOP continues to dominate the programming field and the most widely-used languages are all OOP languages e.g. Python, JavaScript, Java, PHP, Ruby, C++, C#.

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.

You can certainly write any end product without OOP as you could with it. I happen to like OOP because I think more visually and geometrically than linearly. My answer to your question about how to write clear code that maximizes OOP's usefulness is to constantly consider what attributes in subclasses you can or should push up the inheritance chain. For example, I spent a long time working on a piece of software that had pop questions, quizzes, and tests separated into different kinds of objects and database structures. Getting familiar with the commonalities and differences between these user interactions, I was able to restructure the code so that tests extended quizzes, which were a collection of questions paired with answers and users. Maybe this should have seemed obvious to the original coder, but when things grow organically you don't always design them in the ideal way. Restructuring that helped me migrate the database to a simpler, cleaner set of connecting tables that then helped expose a lot of data (user performance) that was much harder to tease out previously. So to me, OOP is more a way of getting at the truth of business / application logic. When trying to solve a small problem, I often write functional inline code. But on a large scale I use objects to clarify the relationships between real world artifacts.

I use c# and will usually create a class where it makes sense for there to be a “state” managed by a bunch of methods. Where you don’t want anyone outside directly playing with that state.

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.

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.

> I use c# and will usually create a class where it makes sense for there to be a “state” managed by a bunch of methods. Where you don’t want anyone outside directly playing with that state.

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.

Usually the state is managed by methods of the class only, with these methods providing the public access or “api”.

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!

"99 Bottles of OOP" by Sandi Metz does a fantastic job IMO of answering the first 3 questions listed.

> 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.

I would read "Refactoring" by Martin Fowler, if you haven't already. It will help you understand what OO code should look like and give you the tools to help get you there.

Personal opinion: The book "Refactoring" by Fowler is one of the worst (tech) books I have ever read. I would rather refer OP to the bible of OOP: Object-Oriented Software Construction by Bertrand Meyer.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact