CS101: Object Oriented Programming
Wow, we’re up to part 6. I suppose it’s time to talk about why we’re doing all of this, huh? Sometimes computer science is a little more art than science. Can’t we just put all of our code in one class? I mean, I wrote it, I’ll remember what it does. This all seems like a lot of effort for something that just works the same in the end, doesn’t it?
Ok, I have to stop. It was physically painful writing that. All of this stuff about classes and objects and inheritance is really really powerful, but with great power comes great responsibility. You are responsible for ensuring that your program doesn’t become a writhing pile of spaghetti code. In case you’ve never heard the term spaghetti code, Urban Dictionary has a fantastic definition:
In computer programming, code that is poorly structured and which makes it hard to update because of multiple undocumented and unexpected links/dependencies. You touch it in one place and you see other things get broken or modified in an unexpected way. Just like sticky spaghetti – you pull one end and you see a number of places start moving.
Horrible, horrible, horrible code, but still (usually) fulfills it’s intended purpose. The English equivalent would be “I is go store buy vodka drink drunk sergawsdawq zzzzzz uuuugh talk loud”. It is completely screwed up in almost every way, but you still know it meant “I am going to the store. I will buy vodka. I will drink. I will get drunk. I will babble incessantly. I will pass out on the couch. I will wake up, go to work, and complain about my hangover.”
That about sums it up. If you write spaghetti code, your coworkers will hate you, your dog will hate you, and you’ll hate yourself when you have to go back and make a change in a few months. It may seem like I’m blowing this out of proportion, but it’s only because there’s an easy solution to this. It’s a pair of concepts called abstraction and encapsulation.
Abstraction is something you do every day. When you get to your car to drive to work, you don’t think “I need to make my car door open, but it’s locked. I guess the most direct way to unlock it would be to shove a coat hanger into the window and pull the locking mechanism, because that’s what’s preventing me from entering my car. Alright, time to get the engine running. I’ll pump some fuel into the engine by hand. Hm, but the spark plugs need power too. I have an extension cord I could use…”
Obviously you would just click the unlock button on your keychain, hop in the car, turn the ignition and get on your way. That’s because you abstracted the function of your car to something as simple as “Push the gas and it goes forward.” This is exactly how your code should work.
Whoever uses your classes, even if its you, should not need to know how they work to know how they are used. This is where the modifiers public and private come in. To review, anything declared as private can only be seen and used by the class itself. Anything declared as public can be accessed and used by anything that has a reference to that object. That could get dangerous really fast; make something public that shouldn’t be exposed and I guarantee you’ll have someone reaching into the back of the TV to change the channel when you’ve already given them a perfectly good remote control. That person may even be you, if you’re not diligent in applying this.
The process of hiding the internal workings of a class behind abstraction is called encapsulation. Your class designs need to be fully encapsulated; make sure they can’t be broken by the user incorrectly using your public methods. By managing all input and output from your classes with carefully chosen public methods, your code will be easier to maintain, debug, and read. You will be able to track down problems faster and prevent unimaginable frustration. To end this post, I’ll leave a quote here from a pretty smart guy explaining this concept:
Objects are like people. They’re living, breathing things that have knowledge inside them about how to do things and have memory inside them so they can remember things. And rather than interacting with them at a very low level, you interact with them at a very high level of abstraction, like we’re doing right here.
Here’s an example: If I’m your laundry object, you can give me your dirty clothes and send me a message that says, “Can you get my clothes laundered, please.” I happen to know where the best laundry place in San Francisco is. And I speak English, and I have dollars in my pockets. So I go out and hail a taxicab and tell the driver to take me to this place in San Francisco. I go get your clothes laundered, I jump back in the cab, I get back here. I give you your clean clothes and say, “Here are your clean clothes.”
You have no idea how I did that. You have no knowledge of the laundry place. Maybe you speak French, and you can’t even hail a taxi. You can’t pay for one, you don’t have dollars in your pocket. Yet I knew how to do all of that. And you didn’t have to know any of it. All that complexity was hidden inside of me, and we were able to interact at a very high level of abstraction. That’s what objects are. They encapsulate complexity, and the interfaces to that complexity are high level.