Realizei uma implementação do exercício de "requisições" do padrão Chain of responsibility usando uma classe abstrata.
Logo me ocorreu de saber a opinião de vocês sobre tal implementação.
E nesse tipo de implementação em específico, me parece ter um template method formando um chain.
O que acham, estou errado, meio certo, certo?
<?php
class Conta
{
public $saldo = 0.0;
public $titular = "";
public function __construct($saldo, $titular)
{
$this->saldo = $saldo;
$this->titular = $titular;
}
}
class Formato
{
public static $XML = "XML";
public static $CSV = "CSV";
public static $PORCENTO = "PORCENTO";
}
class Requisicao
{
private $formato;
public function __construct($formato)
{
$this->formato = $formato;
}
public function getFormato()
{
return $this->formato;
}
}
abstract class Resposta
{
protected $tipoResposta;
public $proxima;
public function enviarResposta(Conta $conta, Requisicao $requisicao)
{
if($requisicao->getFormato() != $this->tipoResposta && $this->proxima != NULL)
return $this->proxima->enviarResposta($conta, $requisicao);
return $this->responder($conta, $requisicao);
}
public function setProxima(Resposta $resposta)
{
return $this->proxima = $resposta;
}
protected abstract function responder(Conta $conta, Requisicao $requisicao);
}
class RespostaXml extends Resposta
{
public $tipoResposta = "XML";
public function responder(Conta $conta, Requisicao $requisicao)
{
$resposta = "";
$resposta .= "<conta>";
$resposta .= "<titular>";
$resposta .= $conta->titular;
$resposta .= "</titular>";
$resposta .= "<saldo>";
$resposta .= $conta->saldo;
$resposta .= "</saldo>";
$resposta .= "</conta>";
return $resposta;
}
}
class RespostaCsv extends Resposta
{
public $tipoResposta = "CSV";
public function responder(Conta $conta, Requisicao $requisicao)
{
$resposta = "";
$resposta .= $conta->titular;
$resposta .= ";";
$resposta .= $conta->saldo;
$resposta .= ";";
return $resposta;
}
}
class RespostaPorcento extends Resposta
{
public $tipoResposta = "PORCENTO";
public function responder(Conta $conta, Requisicao $requisicao)
{
$resposta = "";
$resposta .= $conta->titular;
$resposta .= "%";
$resposta .= $conta->saldo;
$resposta .= "%";
return $resposta;
}
}
class RespostaSemFormato extends Resposta
{
public $proxima = NULL;
public function responder(Conta $conta, Requisicao $requisicao)
{
$resposta = "";
return $resposta;
}
}
class RespondeRequisicao
{
public function resposta(Requisicao $requisicao, Conta $conta)
{
$respostaXml = new RespostaXml();
$respostaCsv = new RespostaCsv();
$respostaPorcento = new RespostaPorcento();
$semResposta = new RespostaSemFormato();
$respostaXml->setProxima($respostaCsv);
$respostaCsv->setProxima($respostaPorcento);
$respostaPorcento->setProxima($semResposta);
return $respostaXml->enviarResposta($conta, $requisicao);
}
}
$formato = Formato::$PORCENTO;
$conta = new Conta(500.00, "Eduardo Cesar");
$requisicao = new Requisicao($formato);
$responder = new RespondeRequisicao();
var_dump($responder->resposta($requisicao, $conta));