PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1
CHAPTER 12 ■ ENTERPRISE PATTERNS

if ( $result = $stmt->fetch() ) {
throw new \woo\base\AppException( "double booked! try again" );
}
$this->doStatement( self::$add_event,
array( $name, $space_id, $time, $duration ) );
}


The purpose of this script is to add an event to the events table, associated with a space. Notice that
I use the SQL statement contained in $check_slot to make sure that the proposed event does not clash
with another in the same space.


Consequences


The Transaction Script pattern is an effective way of getting good results fast. It is also one of those
patterns many programmers have used for years without imagining it might need a name. With a few
good helper methods like those I added to the base class, you can concentrate on application logic
without getting too bogged down in database fiddle-faddling.
I have seen Transaction Script appear in a less welcome context. I thought I was writing a much
more complex and object-heavy application than would usually suit this pattern. As the pressure of
deadlines began to tell, I found that I was placing more and more logic in what was intended to be a thin
facade onto a Domain Model (see the next section). Although the result was less elegant than I had
wanted, I have to admit that the application did not appear to suffer for its implicit redesign.
In most cases, you would choose a Transaction Script approach with a small project when you are
certain it isn’t going to grow into a large one. The approach does not scale well, because duplication
often begins to creep in as the scripts inevitably cross one another. You can go some way to factoring this
out, of course, but you probably will not be able to excise it completely.
In my example, I decide to embed database code in the transaction script classes themselves. As you
saw, though, the code wants to separate the database work from the application logic. I can make that
break absolute by pulling it out of the class altogether and creating a gateway class whose role it is to
handle database interactions on the system’s behalf.


Domain Model


The Domain Model is the pristine logical engine that many of the other patterns in this chapter strive to
create, nurture, and protect. It is an abstracted representation of the forces at work in your project. It’s a
kind of plane of forms, where your business problems play out their nature unencumbered by nasty
material issues like databases and web pages.
If that seems a little flowery, let’s bring it down to reality. A Domain Model is a representation of the
real-world participants of your system. It is in the Domain Model that the object-as-thing rule of thumb
is truer than elsewhere. Everywhere else, objects tend to embody responsibilities. In the Domain Model,
they often describe a set of attributes, with added agency. They are things that do stuff.


The Problem


If you have been using Transaction Script, you may find that duplication becomes a problem as different
scripts need to perform the same tasks. That can be factored out to a certain extent, but over time, it’s
easy to fall into cut-and-paste coding.
You can use a Domain Model to extract and embody the participants and process of your system.
Rather than using a script to add space data to the database, and then associate event data with it, you

Free download pdf