i'm quite new to php and trying to learn. I have 2 similiar classes. I want to create that objects when i pass count and object type. I read some about factory pattern. Here is my factory class:
class AssetFactory
{
private static $table;
public static $objects = array();
public static function Create($asset,$count)
{
switch ($asset) {
case "Item":
self::$table = "items";
break;
case "Job":
self::$table = "jobs";
break;
}
$db = new Database();
$rows = $db->query("SELECT * FROM ".self::$table." LIMIT ".$count);
foreach($rows as $row)
{
self::$objects[] = new $asset($row);
}
return self::$objects;
}
}
and when i need 5 items i use:
$myItems = AssetFactory::Create('Item',5);
when i need some jobs i use:
$myJobs= AssetFactory::Create('Job',5);
item and job are that similiar classes. My question is here, as i said im trying to learn. Am i doing this right? Did i understand factory pattern right? Have any good documents about this(i read everything on php.net, got anything else).
There are few thing that seem wrong in this case.
First of all , there are two similar structures which are used for object creation:
Usually people do not distinguish between the two, and just call them "Factories". So these would be two case where you use a factory.
What you have right now does not fit the description. You are creating some sort of database connection, then getting some data, and then using it for creating a list of objects. This is not a reusable code.
It would be much better if the usage of factory would be something like this :
$connection = new PDO( .. blah.. );
$stmt = $connection->query( 'SELECT * FROM '.$type.' LIMIT '.$count );
$factory = new Factory;
$collection = $factory->buildCollection( $type, $stmt->fetchALL(PDO::FETCH_ASSOC) );
Of course, with factory class which implements this behavior.
Additionally , you might want to watch (assuming, that you haven't seen already) two videos on the subject:
I am far from an authority on the factory design pattern, but I usually delegate the instantiation to a subclass.
<?php
class AssetFactory
{
public static function Create($asset, $count)
{
$objects = false;
switch ( strtolower($asset) ) {
case 'item':
case 'job':
$class_name = 'Asset'.$asset;
$asset_obj = $class_name::getInstance();
$objects = $asset_obj->Create($count);
break;
default:
// Invalid asset
break;
}
return $objects;
}
}
class Asset
{
var $name = null;
var $table = null;
private static $instance = null;
private function __construct() {}
private function __clone() {}
public function Create($count)
{
$objects = array();
$db = new Database();
$rows = $db->query("SELECT * FROM ".$this->table." LIMIT ".$count);
if ( is_array($rows) ) {
foreach($rows as $row)
{
$objects[] = new Item($row);
}
}
return $objects;
}
public static function getInstance()
{
if ( empty($self::$instance) ) {
$class_name = __CLASS__;
self::$instance = new $class_name();
}
return self::$instance;
}
}
class AssetItem extends Asset
{
private function __construct()
{
$this->name = 'Item';
$this->table = 'item';
parent::__construct();
}
}
class AssetJob extends Asset
{
private function __construct()
{
$this->name = 'Job';
$this->table = 'job';
parent::__construct();
}
}