DEV Community

Dimitri Merejkowsky
Dimitri Merejkowsky

Posted on • Originally published at dmerej.info on

Classes Rock

This is the second article in a 2-part series of blog posts that examine the complicated relationships between the real world and object-oriented code. If you haven’t already, you should the first part: classes suck first.

Let’s recap: we used a Robot class to implement the client specifications. It worked well, until we tried to model thestart and stop methods with a mutable state. We concluded that blindly using classes (with methods and mutable attributes)to represent real-world objects was a mistake.

Taking a second look at the code

Let’s look at the code again (minus the stop method), along with the spec:

  • When robots come off the factory floor, they have no name:
def __init__ (self):
    self._name = None
Enter fullscreen mode Exit fullscreen mode
  • The first time you boot them up, a random name is generated:
def start(self):
    if self._name is None:
        self._name = generate_name()
Enter fullscreen mode Exit fullscreen mode
  • When a robot is reset, its name gets wiped:
def reset(self):
    self._name = None
Enter fullscreen mode Exit fullscreen mode

So we were modeling real-world objects with our class after all: the mistake we made was trying to model the robot. But using code to model the specification worked!

If you’re not convinced, consider this: the stop() method is empty because the specification said nothing about what happens when the robot is stopped.

If the specification said something like the robot cannot be reset when it isstarted, then using a stopped attribute may have been a good idea.

Encapsulation

So far we talked only about methods and attributes. There’s another aspect of programming with classes I’d like to examine next: the concept of encapsulation, or how to separate “private” implementation and “public” interface.

Basically, there are some details of a class that matter to the people who wrote the class but that users of said class should not know about.

What does this have to do with the real world? Everything! Let me show you.

A single line telling a whole story

In Python, to signify to users of a class that an attribute is not part of the “public” interface, you prefix it with an underscore, like this:

class Robot:
    def __init__ (self):
        self._name = None
Enter fullscreen mode Exit fullscreen mode

By the way, there are already two pieces of information here:

  • robot names are empty at first
  • the name likely changes over time (otherwise it would probably have been passed as a parameter in the constructor)

But that’s again about the specification. What does it mean to have _name as a private attribute?

Working in teams

Let’s imagine we are writing software inside a big company with several teams. Reading the specification again, it’s clear that the client is extremely worried about robot names: each and every line of the specification talks about it! If there is a bug affecting the robot name, the client is going to get pissed.

And that’s where using encapsulation makes sense: by “hiding” the name attribute from the users of the Robot class, we are actually covering our bases. If someone from another team writes robot._name = "something-else",the client will get mad (the robot name no longer has the correct format), but we can tell him it’s not our fault: the other team should not have broken the encapsulation without asking us first!

Conclusion

So, which is it? Do classes rock or suck at modeling the real world?

Well, it all depend of what you mean by “the real world”. My advice to you is:

  • clarify specifications as much as possible
  • write code that closely resemble the specification
  • use encapsulation when necessary to protect yourself against misuses of your code

When used correctly, classes are a great way to accomplish all of the above, butthey are also easy to misuse.

Finally, let’s go back at our original question: “is modeling the real worldin code worth it?“.

Well, if it allows you to implement the specifications correctly and makesthings easier for you and your team mates, then yes, it’s definitely worth it.

It’s hard, but trying and solve this challenge is what I love about programming.

Cheers!

Latest comments (2)

Collapse
 
willsmart profile image
willsmart • Edited

I’ve got a useful regex substitution for situations like this...
s/\b(\w+) (rocks|sucks)\b/\1 is a tool that is useful for some things but not everything. It’s a power drill or tape measure, not a religion or sports team. Use \1, but avoid deriding or evangelizing it/

Works for pretty much anything to do with coding 🤓

As for classes, they’re a great way to ensure objects implement their advertised interfaces, which can keep things nice and clean code-wise if not overdone, and they have good implementations on most any modern language.
As you were saying, it works out better to think of them as “objects with the same behaviour” than “objects of the same intrinsic type” (whatever that means).

Thanks for the thought provoking post Dimitri!

Collapse
 
dmerejkowsky profile image
Dimitri Merejkowsky

Thanks for the thought provoking post Dimitri!

You're welcome. I love making people think :)