Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I create objects in OOP?

Tags:

object

oop

I've tried searching for answers to this, but it's difficult to phrase and many questions are either about how to create classes or how to do very specific things. I need a bit more of a practical overview - I'm self-taught and I understand what an object is (and how to create them), but I've never seen a good explanation of when to create an object.

This may sound like a strange question that has an answer along the lines of "always", but I've noticed that my OOP code tends to start looking procedural at some point. How do I marry my understanding of both paradigms so that I can write well-structured object oriented code? At some point, there are main functions or bodies of code that need to create variables and instantiate objects then do things like perform conditional testing, so I'm struggling to figure out what should get put into code as an object.

Maybe the answer is that all of those points I just noted above should be encapsulated by another object. I don't know - this is where I'm struggling to move forward from an understanding perspective.

like image 916
armadadrive Avatar asked Apr 29 '26 06:04

armadadrive


1 Answers

This probably isn't a great fit for Stackoverflow, but it's a really good question and should be addressed. You've accidentally stumbled into a common problem in programming: Most "OOP" programs are not actually object-oriented.

The whole point of OOP was to encapsulate complexity. Alan Kay envisioned it originally in terms of biological cells, where all the machinery of the cell is isolated from the outside world, and you can only interact with the cell via messages in and out. So an object encapsulated a complete system, and would itself be made up of objects, and could be composed with other objects to make even larger objects. And everything would communicate with messages, and no one could peek inside anyone else. This is what object-oriented programming was meant to mean, and a lot of writing is still influenced by this idea. But most things calling themselves OOP don't do this (things that do work this way are often called "Actor Model" today and it can be a very effective and robust way to program, epitomized in languages like Erlang).

Most OOP systems today consider an object to be a much less interesting thing (at least in my opinion): just a combination of data and methods that can act on that data. There is great debate within the industry as to whether this is even a particularly useful construct (vs functional paradigms that separate data from methods, or duck-typing paradigms that focus purely on capabilities rather than classes).

But to your question in practice, I'd say in most cases there are two reasons we create objects: to clump data, and to encapsulate responsibility. These are really different things, but in many popular languages they are both treated as "objects."

In the "clump data" case, you create a new object when you have a collection of data that should logically go together. For example, a Point is a collection of two coordinates, and that's a perfectly good "data object."

Regarding "encapsulate responsibility," this refers to what we call the "Single Responsibility" principle. An object should have complete responsibility for one "thing" that you can name. For instance, that "thing" might be "the network connection" or might be "drawing this window." You have a Connection class and a Window class and the like. The real key is naming. You know you have a good class when it's easy to name it, and everything it does seems to follow from the name you gave it. When it's hard to name it, you probably have created the wrong class.

The key lesson for class hierarchies is called the Substitution principle (formalized by Barbara Liskov). If you're going to make a subclass, it must be able to be used everywhere its superclass could be used. So a Corgi IS-A Dog, because everything a Dog can do, a Corgi can do. But, surprisingly, a Square is not a Rectangle. A Rectangle can be created with two lengths. A Square cannot be. The Square-Rectangle problem is probably the most common cause of inheritance mistakes. A good lesson to take away is that inheritance is the wrong tool for many problems. You should favor combining multiple objects rather than inheriting. So when creating your new classes, shallow hierarchies are often best.

As you've discovered, much of what you see called "OOP" is just procedural programming wrapped up in objects. That's very confusing to newcomers. It's pretty confusing to those of us who have been doing this for decades. You just have to see though that.

like image 186
Rob Napier Avatar answered Apr 30 '26 23:04

Rob Napier



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!