22 February 2010

Fábrica - Design Pattern

O padrão de desenho de software fábrica permite a criação de objectos sem especificar as classes exactas que criam esses objectos.


O exemplo abaixo simula uma situação em que temos um ou vários produtos. Cada produto pode ter um ou vários atributos, como cor ou tamanho. Começamos por definir uma class abstracta que lida com o objecto atributos tendo métodos mutadores e assessores e um método que lidara com a forma com os mesmo são colocados numa pagina em HTML. A cor devera ser estar disponível como um radio button e o tamanho como um select.



abstract class atributo
{
protected $nome;
protected $valores = array();

public function set_nome($nome)
{
$this->nome = $nome;
}

public function get_nome()
{
return $this->nome;
}

public function set_valores ($valores = array())
{
foreach($valores as $chave => $valor)
$this->valores[$chave] = $valor;
}

public function get_valores()
{
return $this->valores;
}

public function display() {}
}

class corAtributo extends atributo
{
public function display()
{
$html ='';
foreach($this->valores as $chave => $valor)
$html .= '<input type="radio" name="'.$this->nome.'" value="'.$valor.'">'.$valor;

return $html;
}
}


class tamanhoAtributo extends atributo
{
public function display()
{
$html ='<select name="'.$this->nome.'">';
foreach($this->valores as $chave => $valor)
$html .= '<option radio" value="'.$chave.'">'.$valor.'</option>';

$html .= "</select>";
return $html;
}
}



Para facilitar a escolha dos atributos vamos agora criar uma class fabrica:



class atributoFabrica
{
public static function criaAtributo($tipo)
{
$class = strtolower($tipo).'Atributo';

if (class_exists($class) && is_subclass_of($class, atributo))
return new $class;
else
throw new Exception("O tipo de atributo '$tipo' não tem class.");
}
}


O uso de todo este codigo e tao simples quanto:



$fabricaAtributos = new atributoFabrica();

$tamanho = $fabricaAtributos->criaAtributo('tamanho');
$tamanho->set_nome('Sky');
$tamanho->set_valores(array('2' => '2 metros', '4' => '4 Metros'));

$cor = $fabricaAtributos->criaAtributo('cor');
$cor->set_nome('cor');
$cor->set_valores(array('verde' => 'verde', 'vermelho' => 'vermelho'));

echo '<p>Escolha o tamanho: '.$tamanho->display().'</p>';
echo '<p>Escolha a cor: '.$cor->display().'</p>';