For those of you who are already masters of the Object Oriented paradigm you may find this article rather entry level. I'm writing this for the web developers out there that have been writing procedural code for a while, and are feeling the headaches of dealing with their code base as it grows.
This isn't a complete, "Why Objects Totally Own", article. But I hope it's enough to spark some interest in the procedural programmers out there.
One of the easiest concepts to grasp in OO is something that took me a while to SEE. I've noticed that I do it by default now, I don't even think about it. If you asked me about it 2 years ago I wouldn't have been able to point it out, but now I evangelize it's use.
I'm referring to the encapsulation of a business rule within it's appropriate object.
Plain English version:Solve a problem once and never ever repeat it by using an object.
Quick Note:Generally speaking an object is great for representing various entities in the system you are building. The classic example you'll see over and over again (in OO tutorials) is the "Person" object inside of a Human Resources/Payroll/Employee Management system. When you make a "Person" object you can act on all the data and business rules related to people using the abstract concept of "a person". I don't want to use the Person example, because I'm tired of it. ;)
Let's use an object I've created for my
designer application.
My application deals with
pieces of work that designers upload to the application. A
piece of work can be a logo, an advertisement banner, etc....
I've got an object in my system called "Piece". The Piece object is an abstract representation
of the
piece of work the designer uploaded. All of the business rules pertaining to a Piece are encapsulated within the Piece object. EVERYTHING!
I'm not going to tell you how or where my system stores the file that is uploaded by the designer. I'm not going to tell you how or where my system stores the name of the file. I'm not going to tell you how or where my system stores or retrieves the file path of the file (for display in a browser).
I'm not going to tell you any of that because outside of the Piece object, there isn't another bit of code on our entire planet Earth that knows those business rules.
I'm only going to share with you the same information the rest of my application has. The API of the Piece object.
Let's say you're a developer on my team and you want to build a web page that displays one of the pieces of work a designer has uploaded to the system. Let's say that the ID of the piece, excuse me, "Piece", is sent through the URL to this new page you're working on. You're going to get a Piece object using the ID and whatever object fetching mechanism your application/framework has. With Ruby on Rails, you'd do this.
(This is language specific, and it's just used to illustrate a point. As you develop in your Object Oriented language of choice you'll find out how to create new instances of objects and get the specific one you want based on certain criteria. In this example, the criteria is the ID of the Piece.)URL is this: http://michaelsica.com/piece/?id=23
The object fetching/loading code is this:@piece = Piece.find_by(params[:id])You see the "@piece" part? In Ruby that is simply a variable. That particular variable now contains the specific "Piece" object that relates to the ID we passed in. (If that doesn't make sense, leave me a comment and I'll explain further.)
Now, you as the developer have this "Piece" object that represents the piece with an ID of 23. All you have to do is reference the "@piece" variable when you want to know something about or do something to that Piece.
What was the requirement again? Oh yeah, "build a web page that displays one of the pieces of work a designer has uploaded to the system."
Before you can do that you need to know how to work with the Piece object. You need to know the API. All the business rules and information about the Piece is contained within your "@piece" variable. You're a smart developer so you decide to look up the documentation (API) for "Piece". You see that there is a method (a function on an object) named, "url_path" on the Piece object.
In your web page you can now call that method to get the path to the image, and display it on your page. Like so....
(Again this is Ruby on Rails specific code, but the concept applies to all OO languages.)When Ruby runs this code it will generate the proper HTML. It could be something like:
The "@piece.url_path" is a call to the method, "url_path", on the Piece object, "@piece". But you already knew that, right? ;)
Now, why is this soooooooo neat-o?
You have absolutely NO idea how the image is stored, where it is stored, or how the information was brought together to serve up image's url path. It is all contained within the Piece object. You're now dealing with the abstract concept of a Piece.
I can go into that object at any time and COMPLETELY change how it works and all of the code using the object, i.e. your image displaying code, won't know the difference. I could store the image in a DB and then cache it to a folder under the web site's folder structure on launch day. Then 3 months later, I can decide to store all the images on a file server that is outside of the webroot. The Piece object could then fetch it from there and stash it under the web site's folder structure.
I'm sure some of you are thinking, "I can do this now with a function global function. I'll just pass in the ID and it will return the url path."
Well, let's talk about that for a moment....
Let's say you write this one function to encapsulate the URL path of a piece based on it's ID. Then you find out you have more business rules related to a Piece. You're a good developer so you write more functions so the logic can be encapsulated and re-used. Then you find out you have more business rules related to a Piece. You're a good developer so you write more functions so the logic can be encapsulated and re-used. Then you find out you have more business rules related to a Piece. You're a good developer so you write more functions so the logic can be encapsulated and re-used. Then you find out you have more business rules related to a Piece. You're a good developer so you write more functions so the logic can be encapsulated and re-used. Then you find out you have more business rules related to a Piece. You're a good developer so you write more functions so the logic can be encapsulated and re-used.
Most systems have more than one entity. Let's say you're still working on this application with me. My designer application has the concept of "Clients". You're a good programmer and you want to re-use business logic through functions. So you start writing functions to encapsulate the business logic of all the Client related stuff. With each business rule, you write more functions. And more functions. And more functions, etc.....
The question I now have for you is, "How are you organizing these functions?"
Are you making seperate files that have all the related functions in them, and then making them globablly accessible? Are you going to make files named, pieces_functions.lang and clients_functions.lang?
Guess what.
You've just created groupings of functionality that are closely related to one another that are encapsulated within a single file. That description is pretty damn close to the definition of a "class". A "class" is the name of the file your object code is written in. You put all your methods (i.e. functions) in the class file along with all the data related to the class/object.
(My Piece object, before it is instantiated, is a Piece "class".) But since you're not using objects, you don't get any of the
power of Object Oriented programming. You'll be missing out on inheritance and polyphorism. Not to mention the ability to work with your system at a higher level of abstraction, i.e. this is a Piece, this is a Client, a Client can view a Piece.
I've just scratched the surface of OO in this post. If you'd like me to continue writing about OO programming, please let me know (contact me or leave a comment below).