goncin@wordpress.com:~$ _

Linux, programação e toda sorte de nerdices

PHP: métodos encadeados e __toString()

Para começar, considere esta classe PHP:

<?php

  class Calculadora {

    private $_resultado = 0;

    public function __construct($valorInicial) {
      $this->_resultado = $valorInicial;
    }

    public function mais($n) {
      if(is_numeric($n)) $this->_resultado += $n;
      return $this;
    }

    public function menos($n) {
      if(is_numeric($n)) $this->_resultado -= $n;
      return $this;
    }

    public function vezes($n) {
      if(is_numeric($n)) $this->_resultado *= $n;
      return $this;
    }

    public function divididoPor($n) {
      if(is_numeric($n)) $this->_resultado /= $n;
      return $this;
    }

    public function limpar() {
      $this->_resultado = 0;
      return $this;
    }

    public function igual() {
      return $this->_resultado;
    }

  }

?>

Sim, é uma classezinha boba. E sim, não tem documentação nenhuma 😛 , mas o que ela faz deve ficar bastante óbvio para quem programa em PHP. Meu objetivo aqui é ser didático com algo minimamente útil – em suma, não suporto aquelas classes Foo com métodos Bar que não fazem nada.

Pois bem. O primeiro ponto que desejo abordar nesse artigo é uma tendência em técnica de programação orientada a objetos chamada encadeamento de métodos (em inglês, method chaining ou ainda fluent interfaces). Esse assunto já foi tratado pelo companheiro Jonnas Fonini, mas não custa retomá-lo.

Vamos comparar a utilização da classe listada acima pela técnica tradicional com a utilização de métodos encadeados. Um sobrinho programando o arroz-com-feijão faria provavelmente assim:

<?php

  $calc = new Calculadora(10);
  $calc->vezes(7);
  $calc->menos(5);
  $calc->divididoPor(13);
  $resultado = $calc->igual();

  echo "O resultado de ((10 * 7) - 5) / 13 é $resultado";

?>

Utilizando métodos encadeados, tudo fica mais simples e direto. É o que um profissional faria.

<?php

  $calc = new Calculadora(10);
  echo 'O resultado de ((10 * 7) - 5) / 13 é ' .
    $calc->vezes(7)->menos(5)->divididoPor(13)->igual();

?>

Métodos encadeados tornam o código mais simples e legível. E, para que possam ser utilizados, basta que todos os métodos encadeáveis tenham como valor de retorno a própria instância da classe ($this), como demonstrado pelas linhas em destaque na listagem inicial.

Reparem que o método igual() não é encadeável, pois ele indica que a série de operações matemáticas está encerrada, e que, portanto, o objeto deve retornar o resultado. Todavia, não seria nada difícil “esquecê-lo” ao final de uma longa sequência de encadeamento, e não veríamos resultado algum.

Uma das possíveis soluções para este problema é o método mágico __toString() provido pela linguagem PHP. Em poucas palavras, este método define o que fazer quando se tenta converter um objeto em string (como, por exemplo, utilizando os construtores de linguagem echo ou print). Ao esquecermos o método igual() ao fim do encadeamento, é exatamente um objeto (o valor de retorno de divididoPor()) que passamos ao echo – e ele, por óbvio, não saberá como imprimir o objeto, já que só sabe lidar com strings (implícita ou explicitamente).

<?php

  class Calculadora {

    private $_resultado = 0;

    public function __construct($valorInicial) {
      $this->_resultado = $valorInicial;
    }

    public function mais($n) {
      if(is_numeric($n)) $this->_resultado += $n;
      return $this;
    }

    public function menos($n) {
      if(is_numeric($n)) $this->_resultado -= $n;
      return $this;
    }

    public function vezes($n) {
      if(is_numeric($n)) $this->_resultado *= $n;
      return $this;
    }

    public function divididoPor($n) {
      if(is_numeric($n)) $this->_resultado /= $n;
      return $this;
    }

    public function limpar() {
      $this->_resultado = 0;
      return $this;
    }

    public function __toString() {
      return "{$this->_resultado}";
    }

  }

?>

E isso é tudo. Ao sobrecarregarmos o método __toString(), estamos provendo, para todos os efeitos, uma representação do objeto em string, com a qual echo e print conseguem lidar. Note, contudo, que o valor de retorno do método deve ser explicitamente uma string (razão por que expandi o  resultado do cálculo, numérico, dentro de uma string) – não é possível, neste contexto, contar com a conversão implícita de tipos do PHP.

De quebra, __toString() resolve o problema do esquecimento de igual() para finalizar as operações. A bem da verdade, igual() sequer é mais necessário, tanto que foi retirado da listagem anterior. 😀

Até mais!

Anúncios

4 Respostas para “PHP: métodos encadeados e __toString()

  1. Pingback: Gerador de formulários HTML em PHP orientado a objetos (parte 2) « goncin@wordpress.com:~$ _

  2. Pingback: Twitted by lucasmezencio

  3. Pingback: Wanderson Camargo » Blog Archive » PHP Orientado a Objetos: Encadeamento

  4. Pingback: PHP – Encadeamento de Métodos | Marcelo Boeira - Blog

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: