Saturday, July 19, 2008

Object Oriented Programming is not Procedural programming with structures

For beginners.

Object Oriented Programming is not Procedural programming with structures. They are 2 different ways to think about programs. This is a brief explanation of why the two approaches are different.


Procedural model

Procedural programs are a series of steps. It is the most natural and widespread style of programming. The first HL language - Plankalkül - was a procedural language.

I don't know why Procedural programming is natural... but think about the first program you were taught. Nope, not "Hello World!". More like the program to tie your shoes, or the program to use the big boy's potty. The program they taught you was a series of sequential actions - a procedure.

We use Procedural programming all the time. Cooking recipes for example. Procedural programming is easier to grasp.


The OO model

Object Oriented programming shift the focus away from the procedure to the definition and combination of high-level constructs. These constructs are called Objects.

Instead of being too theoretic, I'll jump into an example to illustrate why this is a major paradigm shift.


Example: Procedural approach

I found a good snippet to illustrate how they differ. Many thanks to Martin Carel.


#!/usr/bin/env python
# Thanks to Martin Carel from http://dev-logger.blogspot.com/

import time
import urllib
from elementtree import ElementTree

feed_link = "http://feeds.feedburner.com/37signals/beMH"
title, published_date = "", ""
TITLE_PATH = ".//item/title"
DATE_PATH = ".//item/pubDate"

while True:
feed = urllib.urlopen(feed_link).read()
tree = ElementTree.fromstring(feed)
fetched_title = tree.findtext(TITLE_PATH)
fetched_published_date = tree.findtext(DATE_PATH)

if title != fetched_title:
print fetched_title, fetched_published_date
title, published_date = fetched_title, fetched_published_date

time.sleep(5 * 60)

Writing this procedure was straightforward. I simply listed the steps needed to get the desired result. I didn't spend a lot of time analyzing my problem.


How am I going to write the OO program?

First, I have to think about the task at hand. Analysis is important. You cannot have a good OO program without understand your problem space well.

For example, I have to identify what concepts of the problem domain I will model as objects. Then I will define the relations between objects and what operations will be possible on them.

Finally, I have to express the program as a combination of the building blocks I defined earlier.


Example: Hybrid functional/OO approach

#!/usr/bin/env python
# Thanks to Martin Carel from http://dev-logger.blogspot.com/

import time
import urllib
from elementtree import ElementTree

class Feed:
class Entry:
def __init__(self, elem):
self.title = elem.findtext("./title")
self.last_updated = elem.findtext("./pubDate")

def __eq__(self, other):
return True if self.title == other.title else False

def __init__(self, url):
self.url = url
self.entries = []

def fetch(self):
feed = urllib.urlopen(self.url).read()
tree = ElementTree.fromstring(feed)
self.entries = [Feed.Entry(e) for e in tree.findall(".//item")]

def has_recent_post(self):
old = self.entries[:1]
self.fetch()
return old != self.entries[:1]

# High-level functionality
feed = Feed("http://feeds.feedburner.com/37signals/beMH")
while True:
if feed.has_recent_post():
print feed.entries[0].title, feed.entries[0].last_updated
time.sleep(5 * 60)


Why is this better?

You know instantly what the program does by looking at the high-level functionality. That's because I was able to match my program to the problem definition by defining the right constructs.

The OO approach forces you to create black boxes. A black box is an abstract element that you can use through it's input and output without having to know it's implementation. Engineers use them everyday.

Black boxes reduce complexity dramatically. It's easy to reason about them. First, each has an isolated and simple function. Second, the interactions between black boxes are explicit. They also reduce complexity by restricting the number of possible interactions. And since a black box can be made of other black boxes, they can organize your program into neat and coherent layers.

Black box designs are easier to understand. You can even choose to know only the boxes and layers of boxes that matter to you. You cannot do the same with a procedural program because nothing is isolated into a component that you can understand independently. You always have to understand how everything interacts.

The OO program is easier to extend because it has well defined extension points. New functionality can be added by adding methods to the class. And it can be used by using the method from the main program.

Lastly, having high-level components allows you to perform high-level operations like late binding and reflection. This is the source of OOP's real power and prowess. It is a very wide and interesting topic so I won't cover that here.