venerdì, agosto 30, 2013

PHP - OOP


Questo post fa parte di una serie preparata qualche anno fa per delle lezioni su PHP.

OOP - Esempio di base

<?php
class WebPage
{
  public function setText($text)
  {
    $this->text=$text;
  }
  public function showPage()
  {
    echo $this->text;
  }
}
$mypage=new WebPage();
$mypage->setText('hello');
$mypage->showpage();

Notare che:
  • manca (volutamente) la chiusura del codice php
  • la pagina prodotta è mooolto scarna (per una sola riga di testo bisognerebbe aggiungere qualche header HTTP, tra l'altro...)
  • tutto il codice è in un unico file, quando sarebbe bene avere invece il codice della classe in un file separato.

Calcolatrice

Vediamo un esempio un po' più complesso:
<?php
class Calculator
{
    private    $operands;
    private    $operator;

    function __construct()
    {
        $this->operands=array();
    }
    
    public function setOperand($n, $v)
    {
        $this->operands[$n]=$v;
        return $this;
    }
    
    public function getOperands()
    {
        return $this->operands;
    }
    
    public function getOperand($n)
    {
        $operands=$this->getOperands();
        if (array_key_exists($n, $this->getOperands()))
        {
            return $operands[$n];
        }
        else
        {
            return false;
        }
    }
    
    public function setOperator($v)
    {
        if (!in_array($v, array('+', '-', '*', '/')))
        {
            throw new InvalidArgumentException('Value ' . $v . ' is not allowed');
        }
        
        $this->operator=$v;
        return $this;
    }

    public function getOperator()
    {
        return $this->operator;
    }
}

Cose da notare:
  • costruttore con nome predefinito
  • definizione di variabili membro private
  • lancio di eccezione
  • interfaccia fluente

Uso della classe:

<?php
ini_set('error_reporting', E_ALL);

function __autoload($className) 
{
    $filename=$className.'.class.php';
    include($filename);
}

$calculator = new Calculator();
$calculator->setOperand(1, 5);
$calculator->setOperand(2, 10);
print_r($calculator->getOperands());
unset($calculator);

Cose da notare:
  • autocaricamento della classe (si evitano includeinclude_oncerequirerequire_once e amenità del genere)
  • visualizzazione ricorsiva di un array (a scopo di debug)
  • deallocazione della memoria utilizzata dall'oggetto (unset)

L'interfaccia fluente dei metodi setters ci consente di scrivere anche cose come queste, più leggibili:

$calculator = new Calculator();
$calculator
->setOperand(1, 5)
->setOperand(2, 10)
->setOperator('*');

echo sprintf("Operator: '%s'\n", $calculator->getOperator());


Esercizio

  1. aggiungere una funzione membro setOperands() che riceve un array di valori come parametro
  2. aggiungere una funzione membro getResult() che restituisce il risultato dell'operazione
  3. definire il comportamento in caso di valori non coerenti (cosa deve succedere se tento una divisione per zero? e se chiedo il risultato prima di aver impostato operandi e operatore?)
  4. definire una serie di casi di test

Nessun commento:

Posta un commento