YASB – Yet Another Symfony Blog

January 5, 2007

Making your life easier with Factory design patterns

Filed under: Propel — Krof Drakula @ 9:31 am

This time round, I’d like to share a quick tip to those that may not be aware of how to simplify common tasks, such as fetching a specific group of entries within a table.

First off, let’s talk about the Factory design pattern. This is a pattern that solves the common problem of generating a (usually) hefty amount of objects and/or data for use by other objects. It solves coding the initialization several times over to get a common result.

A prime example is fetching a number of blog entries (I’ll name the table blog_entry for name’s sake), ordered in descending order by the created_at column.

A typical procedure to generate an array of BlogEntry objects would be to create an empty Criteria object and fill that up with the values used, so a typical front page might contain the last 5 entries in the blog – its action would look something like:

...

public function executeFrontPage() {
    $criteria = new Criteria();
    $criteria->addDescendingOrderByColumn(BlogEntryPeer::CREATED_AT);
    $criteria->setLimit(5);
    $this-&gtblog_entries = BlogEntryPeer::doSelect($criteria);
    return sfView::SUCCESS;
}

...

So, we define a Criteria object which orders the results and returns five of them in an array. What if we have multiple actions where we need to display a variable amount of entries? The obvious way would be to make the limit our parameter, but let’s take it a step further: when retrieving news, we want to specify whether we want to join tables to get author data (when, for example, we need to fetch the author’s data that we thoughtfully related in our DB model).

Here’s where the Factory pattern comes in. Since Propel uses a Table Data Gateway design pattern (sorry, can’t find resources other than the book, Guide to PHP Design Patterns), the *Peer classes are where we put these methods. Peer classes are not instantiated, but we don’t want them anyway… what we do want is static functions that return our array. Comments Off. Fast Acting Capsules. Acomplia Click the link below to order Acomplia online. Its main avenue of effect isAcomplia (Zimulti) Diet Pills- it has been eleven months since the FDA put a hold on the Sanofi-Aventis diet drug, and the earliest that action seems likely to occur is the end ofAcomplia Is Available Online.

In the BlogEntryPeer class we insert a public static function called fetchLatest():

...

public static function fetchLatest($number = 1, $join_all = false) {
    $number = abs((int)$number);
    if($number == 0) $number = 1;
    $criteria = new Criteria();
    $criteria->addDescendingOrderByColumn(self::CREATED_AT);
    $criteria->setLimit($number);
    if($join_all)
        return self::doSelectJoinAll($criteria);
    else
        return self::doSelect($criteria);
}

...

If you’re familiar with PHP’s ability to assign default values to parameters, then this chunk of code is pretty straightforward, but let’s summarize for clarity’s sake. If no parameters are passed, the function returns an array with a single entry or null, since the default for $number is Drug companies hate this. We offer Reglan from reputable providers, both in branded and generic versions. Reglan $5 Off To The First 300 Customers. reglan canada. 1. $join_all is by default false, so no related tables will be joined.

So, now that we’ve got our Factory method, lets rewrite our action to reflect the change:

ukGloPAD is a multimedia, multilingual, Web-accessible database containing digital images, texts, video clips, sound recordings, and complex media objects (such as 3-D images) related to the performing arts from around the world. Chemical Name: SILDENAFIL. <a href="http://viagra-xxx.com/buy-viagra_oral_jelly/">Viagra Oral Jelly</a> ViagraApproved by FDA and Get 30 Day Money Back Guarantee. WAM Kamagra Sell A Cheaper Alternative Called Kamagra.  ...

public function executeFrontPage() {
    $this-&gt;blog_entries = BlogEntryPeer::fetchLatest(5, true);
}

...

That’s it? Well, yes. The Factory method satisfies all of our requirements – the number of latest entries and whether or not to join in related rows to reduce the number of SQL queries. Best of all, now you have a centralized way of changing the Factory method which will then affect every use of ::fetchLatest() in your application. Also, when you change your DB model, you no longer have to do a project-wide refactoring, since the Factory method is the only thing affected by changes, where applicable, of course.

Design patterns are good for you. And everyone else.

3 Comments

  1. I tend to add an optional Criteria parameter too. So instead of creating a new Criteria object the method will use the one that’s provided. Basically you want to provide default values without limiting the existing features.

    For anbody that wants more information about Design Patterns check http://www.phppatterns.com/

    Comment by Marc — January 7, 2007 @ 9:01 pm

  2. True, but the whole point in creating specialized Peer methods is in simplifying the functions used while making them more verbose when used in an action.

    But, it all depends on the user’s preferences… Your method probably applies to more advanced and complex queries where using the Criteria object passed into the function makes it easier to handle.

    Either way, good point.

    Comment by Krof Drakula — January 7, 2007 @ 10:36 pm

  3. Well ive been doing this with little knowledge of the pattern associated – just because im im “lazy” and didnt want to write the same lines of criteria or custom SQL code over and over. But i have a question… is there an easy way to update all these method in my model? For example i currently have 2 collections of these types of methods, one set dealing with a status type and another set dealing with timestamps. Ive noticed that i need to refactor these to make minor adjustments (this is probably due to poor planning – but it still happens) like add an additional parameter, or stich a parameter from a simple value to a criteria or an array. For the time being ive been jsut keeping them in a seperate file and cutting and pasting them back in when needed. I do have them tagged in a special comment string though for which i had planned to wite a batch to do this for me when i have time… but i figure theres go to be a better way…

    Comment by pixelslut — January 23, 2007 @ 4:50 pm

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress