If you’ve been doing web programming for even a small amount of time, you’ll already have noticed the massive amount of repetition when creating, retrieving, updating, and deleting (CRUD) rows from a database. They don’t call it crud for nothin’…
crud
noun
1. any substance considered disgustingly foul or unpleasant [syn: filth]
It ends up becoming so tedious that it can lead you to the brink of insanity. This is where object oriented programming and design patterns come to the rescue — keeping you out of a straight jacket and allowing you to get the CRUD out of your life. That way you can spend your time on more interesting and fulfilling pursuits such as developing a time machine, or writing that great Canadian novel.
No matter what programming language you’re using, your CRUD operations are going to be basically the same. You should be able to abstract a common process for each CRUD operation. You’ll notice that even within these processes, certain CRUD operations are used, e.g. both UPDATE and DELETE make use of RETRIEVE.
CREATE:
- get a new instance of the object to be created
- validate the data on the HTTP request
- if the data is valid, populate the object with data on the HTTP request
- store the object in the database
RETRIEVE:
- use the data on the HTTP request to retrieve an instance of the object to be updated from the database
UPDATE:
- use the data on the HTTP request to retrieve an instance of the object to be updated from the database
- if an object exists, validate the data on the HTTP request
- if the data is valid, populate the object with data on the HTTP request
- store the object in the database
DELETE:
- use the data on the HTTP request to retrieve an instance of the object to be updated from the database
- if an object exists, remove if from the database
There are 3 design patterns in particular that you’ll need to be familiar with in order to come up with a slick solution for cleaning up the CRUD:
- Active Record [PoEAA 160]
- Domain Model [PoEAA 116]
- Table Data Gateway [PoEAA 144]
-
Command Pattern [GOF 233]
-
Context Object Pattern [J2EE 181]
-
The ORM of your choice:
The goal here is to make the CRUD processes reusable for most common cases and easily extendible for special cases. A great way to make processes reusable is to use the Command pattern. The Gang of Four define the Command pattern as a way to: “[e]ncapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations”. What does this mean for CRUD? Well, it allows us to encapsulate the different CRUD processes in objects: one object for each process. We don’t need to know anything about how the command is called or received, so the CRUD processes can be reused in many different contexts.
Speaking of contexts… this is where the Context Object pattern come into play. In the outline of the CRUD processes (see above), I mentioned that data will be coming from an HTTP request. In most cases, HTTP requests are what you’ll be familiar with. You’ve probably spent a lot of time using $_REQUEST (or $_GET and $_POST)? There are some cases where data won’t be coming in through an HTTP request, such as, if your php app is used on/called from the command line or if the data you’re receiving is tied into a different protocol, such as SOAP.[1] Context objects are used to encapsulate the request data so that the Commands can work with a common interface, i.e. treat all requests as though they are the same, regardless of how the request data is received by the application.
The last, and arguably the most important aspect of CRUD operations, is your ORM. There is no CRUD unless there is something to apply CRUD to. It’s your ORM that supplies the objects that will be created, retrieved, updated, and deleted. As far as ORM’s go, you can build your own (depending on the needs/requirements of your application) using any one of the 3 ORM patterns listed above, or you can use a 3rd party tool like Propel. The pro’s and con’s of these options are out of the scope of this article, but if you’ve read this far and still haven’t decided on an ORM, you should probably do that before reading on…
So that’s CRUD in a nutshell. Love it or hate it, you’ll have to deal with it. In my next article, we’ll start dig into the CRUD and see how the different design patterns (described above) work together to form a solid solution. I’ll focus on the Command pattern first and provide some concrete PHP code to help you get started on your implementation. The third and final article will cover the Context Object pattern and your ORM pattern of choice. By the end, you’ll have the skeleton of a CRUD implementation at your finger tips.
Footnotes:
[1] although a SOAP request is generally transferred over HTTP, the SOAP data will often be extracted from the HTTP request and put into a SOAP specific object before being passed off for processing.
great article!! thanks for sharing all this information!
btw, as a reference for the context object patern, you could use this link! http://www.corej2eepatterns.com/Patterns2ndEd/ContextObject.htm