Monday, November 10, 2008

Why use Object Oriented Programming…

Do you get this feeling, “why use classes and objects un-necessarily when functions can achieve the same in a simpler manner?” If yes, this article is for you. It took me about 3-4 months to fully realize the potential of OOP over structural paradigm. The only way you’ll realize the importance of OOP is when you write big code, I mean BIG, around 50K lines or so.

Here’s the scenario, consider yourself as a topnotch programmer who has written about 50,000 lines of code :) , say you’ve written some utility functions (around 800 of em) and have packaged them in a library.

Why does big code gets messy and un-manageable??

Problem 1…Functional clutter

From the usage point of view, the person using your library will probably be confused will all the functions you’ve provided (they’re about 800!!!) and moreover they have to remember all the parameters to the function, its behavior etc…

Ex- funcA(param1, param2, param3)
Param1, param2 are numbers…
Param3 can take values 1,2,3

1 would mean that the function will add param1 and param2…
2, 3 means it’ll perform multiplication and division

The whole point is that it’ll get real tough to remember the functions and its behavior, parameter’s when there are too many of them. Furthermore not all of the functions are of utility value. What I mean is that there will be some functions that are used by other utility value functions.

Ex - funcA() uses funcB() and funcC() to do its tasks. The end user is only concerned with funcA and not with funcB and funcC.


Problem 2…The headache of global variables

The usage of global variables is the most annoying thing for me. It’s very easy to confuse a global variable with a local one or vice-versa. Also tracking the usages of global variables is considerably difficult. It also increases dependencies between the functions.

Ex-

int x; //(global variable)

void func1()
{
//Uses global var x (reads and modifies)
}

void func2()
{
//Uses global var x (reads and modifies)
}


In this case, there exists a dependency between func1 and func2 indirectly via global variables…

How?
If in the future, you’ve found some bugs in func1 and corrected…it might as well affect func2 as they share the same global variable (dependency).

Problem 3…Unmanageable Associations

Consider a game consisting of 300 circles which are moved randomly (say). Every circle has three status variables associated with it.

x, y coordinate and the radius.
Here’s how your code would work.


loop
{
//Clear screen
//Draw all circles by reading their respective status variables
//Update the positions of all the circles by updating the status variables,
//using some logic
}


The thing is that there are three variables with each circle…So that makes it 300 * 3 variables

You’ll probably end up naming variables as
Int x1, y1, r1, y2, r2….x300, y300, r300

What if there are more objects in the game, like clouds, trees etc (even more status variables). All of this makes the code look messy and also makes the associations harder. You’ll soon start confusing which function operates on what and which variable is associated with an object (circle in this case)

So what are the solutions to these issues? If you think about it’ll almost seem obvious.

Solution to problem 2 & 3

In the world of OOP objects form the building blocks of the code. Suppose you’re coding a game, just think of any sprite (something that’s rendered onto the screen) as an object.

An object is just like any other real world entity.

- It has certain attributes or properties associated with it. In case of the circle consider its status variables as its attributes.

- Has certain operations associated with it. You could have associated an operation (function) ‘move()’ with the circle object that would randomly alter its attributes. Also a function called ‘draw()’ can be added to render the circle onto the screen.

Now there’s no more confusion…All the variables and operations are ‘encapsulated’ within an object


Circle (class or prototype of an object)
--------------------------------------
(Attributes)
--------------------------------------
Int x
Int y
Int radius
--------------------------------------
(Operations)
--------------------------------------
Move()
Draw()
--------------------------------------

Class is just a template; an object on the other hand is an instance of the class having its own attributes.

Moreover there is no longer a menace of global variables as all the attributes (variables) are encapsulated within classes.

Solution to problem 1


To avoid the confusion all the related functions and shared global variables could be encapsulated within a class.
Ex- Suppose you have some functions that perform certificate auth, encryption, decryption etc…You could combine (associate, encapsulate) them all in a class named security. Make all the shared global variables its attributes.

As far as the utility of the function is concerned, OOP introduces access modifiers such as public, private etc…

Make the real utility valued functions as public. The supporting functions can be made private so that they cannot be accessed directly from the object.

This is only the beginning (yea, I know it’s a movie dialog). You haven’t tasted the real power yet. Apart from the issues I discussed, the key strength of OOP is in inheritance and abstraction.
I’ll discuss more about those in my next post. I hope this article was useful.

1 comment:

  1. dude...tht wz good...now write one on uml as promised....well sme of the stuff here...u already told me remember??

    ReplyDelete