CF101
Baking Object-Oriented Pizza with ColdFusion
Procedural programming and OO programming buzzwords
Jun. 10, 2007 01:00 PM
So, Let's Put Some CFCs into the Mix
This whole example is about pizza. Most of the functions we're doing are being done on the pizza. So, we can create a Pizza CFC to handle a lot of this functionality. A few methods to put in the CFC are Bake, Prepare, Cut, and Deliver. Instance variables in the CFC might be price, ingredients, and the order information. Instead of executing multiple custom tags and passing data back and forth, we pass the data into the pizza component, and then merely call the component's methods (or functions) to act on the data. A sample of this approach can be seen in Listing 1. As with the custom tags, I didn't flesh out the code of the CFC.
Is the CFC in this example an object? Technically it meets the definition of an object from the OO paradigm. It also meets the definition of an Abstract Data Type (ADTs) from the procedural paradigm. For all intents and purposes objects and ADTs are the same. They are containers for data that also abstract functionality to perform actions on the data. Today everyone calls them objects because that's a buzzier word.
Add Some Object Orientation
Object-oriented programming is supposed to build a model that mimics the way things really operate in the real world. In procedural programming, your model is built to make it easy for the computer to process. I once heard it said that procedural is requesting the data and doing things to it. Using this as a basis, Listing 2 is very procedural. It's not mimicking the real world; it's breaking things up into small chunks to send to the computer processor for processing.
A pizza doesn't know how to deliver itself to the customer. It doesn't know how to prepare itself. It does not know how to bake itself, or cut itself into slices. In an OO model, this functionality wouldn't be put on a pizza object. An OO is geared towards telling your "things" how to act on the data they already have. Next we'll modify the example to be a bit more OO.
The pizza doesn't actually do anything in the real world. The robots or customers do the real tasks. If we were to create an object for it, it would just be a data container to pass around to objects. Here are a few of the actions that occur in the system:
- OrderPizza: This would be something that the customer does.
- PreparePizza: This is something that the cook does.
- BakePizza: This is also something done by the cook.
- Cut Pizza: The cook cuts the pizza.
- Receive Order: When the customer orders the pizza, the waitress gets the order. When the waitress gets the order, she needs to pass it to the cook. As such both the waitress and the cook may have a method for receiving the order.
- Receive Pizza: When the cook is done cutting the pizza, he needs to give it to the waitress. The waitress has to respond to the receive pizza method. When the waitress gets the pizza, it must be delivered to the customer, and as such the customer must also respond to the Receive Pizza method.
We come out of this description with a customer object, a cook object, and a waitress object. You can see these in
Figure 1. Most likely a full-fledged application would also include a pizza object and an order object, used as data containers as arguments to the methods.
With all these objects, our code changes quite a bit. This line will start the order process:
Customer.OrderPizza();
This assumes that a customer object is already created, of course. The customer OrderPizza function would look like this:
<cffunction name="OrderPizza">
<cfset Waitress.RecieveOrder(MyOrder)>
</cffunction>
The Waitresses ReceiveOrder method would look like this:
<cffunction name="OrderPizza">
<cfargument name="Order" type="order">
<cfset Cook.RecieveOrder(MyOrder)>
</cffunction>
The cook's ReceiveOrder method would look like Listing 2. The cook does a lot of work in this process compared to the customer or waitress. The waitress gets the pizza back from the cook:
<cffunction name=" RecievePizza">
<cfargument name="pizza" type="Pizza">
<cfset customer. RecievePizza (arguments.pizza)>
</cffunction>
The customer gets the pizza from the waitress using this method:
<cffunction name=" RecievePizza">
<cfargument name="pizza" type="Pizza">
<cfset customer. Devour (arguments.pizza)>
</cffunction>
Instead of one CFC with lots of data and functionality, we have a lot of CFCs with very little data and functionality. The order is passed around, down the chain from the customer to the waitress to the cook. The cook processes it and sends a pizza back to the customer.
Conclusion
A lot of ColdFusion programmers started programming without using any encapsulation at all. Business logic and display code was mixed in a single template. This was partially due to limitations within the language of ColdFusion. When I talk to them they refer to this old school CF method of programming as procedural, even though it had very little to do with procedural programming. I hope this article enlightened you to a few of the differences between procedural programming and object-oriented programming.
About Jeffry HouserJeffry Houser has been working with computers for over 20 years and in Web development for over 8 years. He owns a consulting company and has authored three separate books on ColdFusion, most recently ColdFusion MX: The Complete Reference (McGraw-Hill Osborne Media).