Friday, October 10, 2008

Object orientation

This is a continuation of my previous object orientation discussion. There, I gave my introductory thoughts on why object is beneficial in most circumstances. Not just as a fancy paradigm buzzword but as actual sustainable design. The class provides developers a taxonomic mechanism to represent abstractions in both the problem domain and the solution domain.

Encapsulation

Encapsulation in the context of object orientation means data concealment. But why do developers want to hide the internal data structures? Moreover, in cases where the developer is working by himself on some component, they are basically hiding the data from themselves.

So why is encapsulation an important concept in object orientation? The goal behind encapsulation is to hide irrelevant details from the outside world. A real life example of encapsulation is as follows. When you drive a car, several engineering details are hidden away from the driver. All the driver wants to do is move forward. When the puts the gearshift into "drive", several complex actions are executed by complex structures. Why doesn't the driver care about any of this? Because she can accomplish her goal without this knowledge overhead.

There are two sides of encapsulation. The first side being data concealment. The second being behavioural concealment. There are times when hiding functionality from the outside world is useful. Such as when there exists a method that is only used by other methods of the same class.

The following example is Python code that does not incorporate encapsulation into the design:

class BlogEntry:
def __init__(self):
self.title=''
self.body=''

if __name__=='__main__':
blog_entry_obj=BlogEntry()
blog_entry_obj.title='Test'
blog_entry_obj.body='This is a test.'

Although by default all attributes of Python instances are publicly accessible, this example directly uses attributes of the instance. This is not good programming practice and violates the idea of an encapsulated abstraction. Here is a new implementation:

class BlogEntry:
def __init__(self):
self.title=''
self.body=''

def set_title(self, title):
self.title=title

def set_body(self, body):
self.body=body

def get_title(self):
return self.title

def get_body(self):
return self.body

if __name__=='__main__':
blog_entry_obj=BlogEntry()
blog_entry_obj.set_title('Test')
blog_entry_obj.set_body('This is a test.')
All we have done here is add a few methods to the class definition and invoke them where instances of the class are used. The key idea here is that we hide the internal structure from the main program (in this example). In the first example, we alter the instance state directly. In the last example, we alter the instance state behaviourally. This is the proper way to interact with software objects. We are only concerned with how we can behaviourally affect instances.