Click here to Skip to main content
Click here to Skip to main content

Tagged as

Design patterns Part I – Factory

, 16 Aug 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
The second part of a set of explained design patterns
The problem:
 
We need a method that could generate us different "products" based on different conditions or, why not, depending on the context. If we didn’t know about design patterns we would solve this by creating an endless if then else set of conditions. I know, this is the fastest solution that comes into your head, but have you ever think of the consequences of this practice? What will you do when you will have to add some other conditions? We need some automation of this process.
 
Here comes the Factory Pattern, a creational design pattern, which consists (or make use) of the Abstract Factory Pattern and the Factory Method Pattern. Let’s see what’s the role of every each of this two:
 
* Abstract Factory Pattern centralize decision of what factory ( = the thing that generates us "products") to instantiate.
* Factory Method Pattern centralize creation of an object of a specific type choosing one of several implementations
 

Factory pattern is usually used in framework’s libraries design, where appears the need to create objects of types which may be subclassed by applications using the framework.
 
Oh, a lot of theoretical terms, ah? Let’s skip this and go ahead with the implementation. Think about some items, which can be video items, photo items or image items, for now. Depending on the type, there should be a different handling of the items. Knowing the problem we should find a solution and the first one is a simple procedural check on the type of the item and then continue with coding. This is rather tricky because we should perform this check every time we handle items. Using object oriented code and the factory pattern we get rid of this "every time check" and let the factory’s products to handle this job.
 
The solution (implementation):
 
Example for procedural mode:
 
//index.php – display items
We assume that we have in $items a list of items.
foreach($items as $key=>$item){
    if($item['type'] == 'video'){
        display_video_item($item['id']);
        }
        elseif($item['type'] == 'audio'){
        display_audio_item($item['id']);
        }
        elseif($item['type'] == 'photo'){
        display_photo_item($item['id']);
        } //I’ve use a conditional statement to iterate through all items’s types
}
 
//display the number of items
……
if($item['type'] == 'video'){
    echo count_video_items();
}
elseif($item['type'] == 'audio'){
    echo count_audio_items();
}
elseif($item['type'] == 'photo'){
    echo count_photo_items();
}
 
And these are only two situations where we need some kind of classification based on item type. What should we do when somebody ask us to add a text item type, or to split photo item type into other categories ….
 
Example for object oriented mode:
Well, we know that we have 3 item types: video, audio and photo, so … we can develop 3 classes and why not make use of the abstract factory too.
 
abstract class Item{
       public function countItems(){
          $count = 0;
              //get number of items of some type and put it in $count
          return $count;
      }
 
      public function displayItems(){
         //get items of some type and display them
      }
}
 
//here we can add what ever validations and methods (related to the working type) that we want (this classes inherits all the methods of Item class)
class VideoItem extends Item{
       public function getTitle($id = 0){
          //get the title of the item with ID = $id
       }
}
class AudioItem extends Item{
    public function getDescription($id = 0){
        //get the description of the item with ID = $id
        }
}
class PhotoItem extends Item{}
 
class ItemFactory{
    public static function createItem($type){
       $baseClass = 'Item';
       $targetClass = ucfirst($type).$baseClass;
 
       if (class_exists($targetClass) && is_subclass_of($targetClass, $baseClass))
           return new $targetClass;
        else
           throw new Exception("Item type '$type' is not recognized.");
    }
}
 
$types = array('video', 'audio', 'photo');
foreach($types as $key=>$type){
    ItemFactory::createItem($type)->displayItems();
    ItemFactory::createItem($type)->countItems();
}
 
You can notice that this is an elegant solution indeed. Also, you can ask yourself why to use so many classes to do that. Well, the answer is very simple, these classes can be used in other application with a slight of modification.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

ro-php-code
Web Developer MediaPro Interactiv
Romania Romania
No Biography provided

Comments and Discussions

 
GeneralThese aren't really tips PinmemberTheyCallMeMrJames16-Aug-10 12:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 16 Aug 2010
Article Copyright 2010 by ro-php-code
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid