Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Design Patterns I - erro no acesso ao deposita

Boa noite Senhores

Não consegui entender o por que do erro de Fatal error: Fatal error: Call to a member function deposita() on null in C:\wamp64\www\dp1\Conta.php on line 11 . Abaixo minhas classes: Classe conta:

<?php
    class Conta {
      protected $saldo;
      protected $estado;

      public function saca($valor) {
        $this->estado->saca($this, $valor);
      }        

      public function deposita($valor) {
       $this->estado->deposita($this, $valor);
      }

      public function getSaldo() {
          return $this->saldo;
      }

    }
?>

Estado da Conta, Positivo e Negativo :

<?php
      interface EstadoDaConta {
      public function saca(Conta $conta, $valor);
      public function deposita(Conta $conta, $valor);
    }
?>

<?php
    class Positivo implements EstadoDaConta {
      public function saca(Conta $conta, $valor) {
        $conta->saldo -= $valor;

        if($conta->saldo < 0) $conta->estado = new Negativo();

      }

      public function deposita(Conta $conta, $valor) {
        $conta->saldo += $valor * 0.98;
      }

?>

<?php
    class Negativo implements EstadoDaConta {
      public function saca(Conta $conta, $valor) {
        throw new Exception("Sua conta está no vermelho. Não é possível sacar!");
      }

      public function deposita(Conta $conta, $valor) {
        $conta->saldo += $valor * 0.95;
        if($conta->saldo > 0) $conta->estado = new Positivo();
      }

    }
?>

Para mostrar fiz assim no index

<?php


    require "Conta.php"; 
    require "EstadoDaConta.php";
    require "Positivo.php";
    require "Negativo.php";
    require "RealizadorDeInvestimentos.php";
    require "EstadoDeUmOrcamento.php";
    require "Aprovado.php";
    require "EmAprovacao.php";
    require "Reprovado.php";
    require "Finalizado.php";


    $conta = new Conta(500);
    echo $conta->getSaldo(), '<br />';
    $conta->deposita(10);
    echo $conta->getSaldo(), '<br />';
    $conta->saca(100);

Fiz como no exemplo postado. Agradeço as dicas.

4 respostas

O problema é que, a classe Conta não está iniciando com um estado padrão. Modifique o código como abaixo.

<?php
    class Conta {
      protected $saldo;
      protected $estado;

      //implemente o construtor
      function __construct(){
           $this->estado = new Positivo();
           $this->saldo = 0;
      }
      public function saca($valor) {
        $this->estado->saca($this, $valor);
      }        

      public function deposita($valor) {
       $this->estado->deposita($this, $valor);
      }

      public function getSaldo() {
          return $this->saldo;
      }

    }
?>

Obrigado Tarcisio, fiz os ajustes. Mas agora ocorre o erro de que nao pode acessar a propriedade protected Conta::$Saldo na classe Positivo.php. Tentei alterar para private mas houve o mesmo erro com o private.

Cria um método setSaldo na classe Conta.

<?php
    class Conta {
      protected $saldo;//Deixa assim mesmo...protected
      protected $estado;

      //implemente o construtor
      function __construct(){
           $this->estado = new Positivo();
           $this->saldo = 0;
      }
      public function saca($valor) {
        $this->estado->saca($this, $valor);
      }        

      public function deposita($valor) {
       $this->estado->deposita($this, $valor);
      }

       public function getSaldo() {
          return $this->saldo;
      }

    //implementa assim
     public function setSaldo( $saldo ) {
          $this->saldo = $saldo;
      }

    //Vai precisar do setEstado tbm
    public function setEstado( EstadoDaConta $estado ){
             $this->estado = $estado;
        }

    }
?>

Nas classes Positivo e Negativo...usa esse método e não acessa direto a propriedade. Ex abaixo

<?php
    class Positivo implements EstadoDaConta {
      public function saca(Conta $conta, $valor) {
        $saldo = $conta->getSaldo() - $valor;
        $conta->setSaldo( $saldo  );


        if( $saldo < 0 ) $conta->setEstado (new Negativo());

      }

      public function deposita(Conta $conta, $valor) {
        $saldo = $conta->getSaldo();
        $conta->setSaldo( $saldo += $valor * 0.98 );
      }

?>
solução!

Tarcisio, muito obrigado. Deus lhe abençoe. Funcionou OK.

É que não uso PHP no dia-a-dia . As vezes não é tão simpes para mim :), sabe? Mas amo a área de desenvolvimento e por isso me preparo para alguma oportunidade.

Valeu.