I originally wanted to name this post “Object Oriented Concepts – Contd….”, but then the Hamletian dilemma came to mind. Every programmer faces this, even today, many years after OO has been widely accepted. Part of the problem is that the OO paradigm requires a change in how we think about a problem.
As we saw earlier, in traditional languages, we always think “how to do a task” in a procedural sense. This we could adapt to – after all, we humans are good in giving instructions and making recipes and grocery lists. Programming was a natural extension of this – we told the computer what to do and how to do it. We told the computer what to do while feeding data (nouns) required as parameters to these commands (verbs).
When it comes to OO, we have to start thinking what will be the objects we need and “leave” it to those objects to do the work. Really, it’s just repackaging, but it’s not easy. We are now forced to think of everything in terms of objects. If it’s objects like animals, cars, people, etc. that are typically used in examples about OO, we can understand. But the moment we try to come up with objects for abstract concepts and purely action oriented tasks, it becomes a daunting task.
Baking a Cake
For e.g., let’s look at a simple problem of baking a cake (no disrespect to the chef in the kitchen, but let’s abstract it as a simple task here for a minute). A recipe typically talks about how to get, do, heat, bake, etc. All verbs. Interspersed will be details about data to be used – how much flour, how much sugar, what temperature, how many minutes, etc. These “nouns” are used as parameters to the recipe and off we go. Of course, every now and then, people try to “reuse” recipes by switching ingredients.
This simple recipe for a cookie highlights these points. It has an instruction with 3 simple steps to make delicious cookies. It has some ingredients (attributes) mentioned – dough, apricot jam, and parameters like temperature at 350 degrees, time for 15 – 18 minutes and 1/3 cup of jam. It is straight forward and it even “reuses” recipe for “basic sugar cookie dough”! We certainly know who is making this cake – you, and the ingredients and implements you will be using.
In our abstraction in a procedural language, we created a program with the instructions to bake a cake. We probably broke down each step into a separate procedure (or function), and created a main function that looked like the recipe and called these functions to get the baking done. We created some variables outside of these functions for the parameters required. This works and is even simple to write. But, we assume a lot of things here, like the main function itself acts like the baker executing the instructions. Controlling the oven may be built in as a built in function, but at some point, it has to call something to make it happen.
In OO, the task gets a bit more complicated! First, you would have to start thinking differently. Now, you will have to think about the nouns first. Of course, there is cake, the final product. But, there is also the bowl, oven and a fictitious baker – may be you, but object none the less. These other objects were included in our procedural programs, but were not given much importance. Any reusable, replaceable parts of the program will now have to be separate objects. In our example, if we make the Oven and the Baker and bowl objects correctly, they could be reused in making/baking pies as well as switch to make or even pot roast! Guess what, you can even replace the baker easily!! This is what makes OO so reusable and to some “so bloated!”.
If you are interested in OO cakes, here is a link on a cake OO.
So, To OO or Not to OO?
OO is almost everywhere around us. Language after procedural language (recently PHP, Coldfusion, ABAP, Flash ActionScript) have added OO capabilities in recent years. But then, there are also others that write about the difficulties and shortcomings of OO. The post titled Debate Still Rages Over Object-Oriented Programming discusses such dilemma. While you are there, don’t forget to check out Marc Funaro’s original post here: How OO Almost Destroyed My Business. He has articulated very nicely, why he couldn’t and didn’t have to switch over to OO completely. And see here for a funny take on Java’s OO techniques! Irrespective of such views, OO is here to stay. Even if you don’t use OO technology currently, chances are, sooner or later you may be exposed to it.
OO methodologies could get complex and could actually distract a developer from the original goal of getting a working program quickly. The general rule of thumb I have, is to use procedural for any small (read quick and dirty – most of my utility programs and scripts fall under this) programs and use OO methodology for any larger (business, corporate, enterprise, framework) programs and programs that have the potential to grow in the future. (The truth is, even the quick and dirty program/script could outgrow their originally intended lifetime and objects do creep into those every now and then!). OO definitely enforces certain planning ahead of time, so it takes a bit longer to develop it upfront, but if a program lives long enough, re-usability makes up for the cost over time.
In the cake example above, if I am just making a cake for the family on a weekend, simple procedural implementation would be fine! But, if you are going to be making a cake each weekend or thinking of starting a bakery with several branches down the road, then I better start thinking in OO terms, so we don’t have to re-invent a lot of stuff later.
General Design Considerations
Irrespective of whether we use OOP (OO programming language) or not, we are bound to use the modern techniques like Abstraction, Encapsulation, Inheritance and Polymorphism in our program designs. Underlying all these, is the code reuse, data hiding and of course modular design. These, of course, are not OO by themselves, but are the foundations of OO techniques. By nature of it, OO is almost automatically modular.
Keep Your Code Clean
If the code is not “cleanly” written, even you cannot understand it a year later. By clean, I mean well commented (documented) and following some coding standards and best practices.
As for coding standards, what’s good for one language isn’t always good for another – for e.g, in Java, we follow Camel case for naming variables while in PB, identifiers are mostly in lower case. So, if your system includes programs in different languages, make sure to include language specific standards as well. Also, best practices for any language may change over versions. For e.g., there may be newer constructs and/or functions may be available in a later versions that are more efficient than what was available earlier. Make sure to keep up with those in your programs.
OO Note: OOP languages such as Java promote commenting and documenting of the programs easier, with the Javadoc tool (even more so, with IDEs like Eclipse and Netbeans). A well written framework for Java, actually enforces some coding practices automatically. But we can achieve such coding practice with libraries of well written API. A well commented header file distributed along, could act as the documentation for the API.
Keep It Modular
By breaking down your program into smaller modules, your program becomes more manageable. If your program includes specific modules for various functionalities, it will be easier to replace or rewrite or even add a specific module without affecting the entire program. For e.g., if you isolate all database related functions to a separate module, then if your database changes, then all you have to do is to replace this one module. In our cake example above, we could simply add an object for Microwave and start using it instead of Oven, if oven breaks down!
OO Note: Writing such “modular” programs comes naturally in OO languages as the program is essentially built around objects (or classes). But this concept itself is not new. For e.g., in C, you can achieve this by keeping different modules in separate source files), your program becomes more manageable.
Make the Code Reusable
How many times have you “cut and pasted” your code from one source file to another to “reuse”? If the program is properly designed, then the reuse would be much easier and automatic.
OO Note: In OO, inheritance promotes reuse naturally. A well written framework or class libraries contain reusable classes and methods. Apart from using the classes in the framework themselves, one could extend those via inheritance and thus more custom classes for others in a company to reuse. For e.g., you can create custom loggers specific for your need, by extending classes in log4J library.
But again, this is not specific to OO. In a procedural language like C, one could build libraries of reusable functions. While C doesn’t allow extension through inheritance, reuse can be achieved through composition. An inheritance is typically defined by a is-A relationship, while a composition by a has-A. Here is an excellent article that compares the two.
Filed under: CodeProject, Programming
Tagged: Methodologies, Object Oriented