2010-09-03 3 views
8

Sto passando all'utilizzo di OOP per tutti i miei progetti, storicamente tutto ciò che ho creato è stato piuttosto ridotto e OOP non sembra essere una scelta efficiente, ma ora con grandi progetti lo è. Tuttavia, più recentemente mi sono imbattuto in domande sempre più "migliori pratiche" che ho e non riesco a trovare la risposta.Teoria PHP OOP - Errore durante la verifica all'interno o all'esterno della classe?

Per esempio, immaginate Ho la seguente:

class numbers{ 

    function __construct($number){ 
     $this->number = (int)$number; 
    } 

    function add($add){ 
     $this->added = $this->number + $add; 
    } 

    function multiply($multiply){ 
     $this->multiplied = $this->number * $multiply; 
    } 

    function minus($minus){ 
     $this->minused = $this->number - $minus; 
    } 

    function number(){ 
     return $this->number(); 
    } 
} 

Ora diciamo che voglio applicare add, quindi multiply e poi minus. Ogni stadio può fallire (non l'ho incluso nell'esempio, ma immagino che sia lì). Questo è dove il mio problema si trova, devo fare:

$numbers = new numbers(8); 
if($numbers->add(7)){ 
    if($numbers->multiply(6)){ 
     if($numbers->minus(7){ 
      echo $numbers->number(); 
     }else{ 
      echo 'error minusing'; 
     } 
    }else{ 
     echo 'error multiplying number'; 
    } 
}else{ 
    echo 'error adding number'; 
} 

O devo avere quella parte nel mio costruttore, come:

class numbers{ 

    function __construct($number){ 
     $this->add(6); 
     $this->multiply(9); 
     $this->minus(7); 
     if($this->error){ 
      return false; 
     }else{ 
      return true; 
     } 
    } 

    function add($add){ 
     $this->added = $this->number + $add; 
     if(!this->added){ 
      $this->error = "couldn't be added"; 
     } 
    } 

    function multiply($multiply){ 
     $this->multiplied = $this->number * $multiply; 
     if(!this->multiplied){ 
      $this->error = "couldn't be multiplied"; 
     } 
    } 

    function minus($minus){ 
     $this->minused = $this->number - $minus; 
     if(!this->minused){ 
      $this->error = "couldn't be minused"; 
     } 
    } 

    function number(){ 
     return $this->number(); 
    } 

    function error(){ 
     return $this->error(); 
    } 

} 

e poi semplicemente fare:

$numbers = new numbers(5); 
if($numbers){ 
    echo $numbers->number(); 
}else{ 
    echo $numbers->error(); 
} 

Spiacente se l'esempio è lungo (anche ignorando gli errori, l'ho scritto qui solo per delineare quello che sto cercando di fare, questo non è il codice che sto usando ...) ma non so come esprimere la frase domanda senza un esempio. Fondamentalmente, dovrei controllare gli errori all'interno della classe o dovrei farlo fuori quando chiamo la classe?

+0

@FrustratedWithFormsDesigner: Perché la modifica? Il metodo è chiamato 'meno' - è perfettamente accettabile utilizzare il modulo di verbo in questo caso. Penso che la tua modifica abbia reso la domanda più confusa, non meno. – Gian

+0

@Gian: Quando si utilizza un nome di metodo come un verbo, di solito è meglio chiarire che si sta parlando del metodo, non di un verbo generale, più simile. Questo: "Voglio' add', quindi 'moltiplica' e quindi' meno'. " chiarisce che stai parlando di chiamare il metodo "meno", non cercando di usare male la parola "meno" come verbo. – FrustratedWithFormsDesigner

+3

Nel mondo di lingua inglese, si chiama sottrazione. Meno è un segno. –

risposta

11

Ha quasi sempre senso applicare la coerenza sugli aggiornamenti all'interno della classe (vale a dire ogni volta che un metodo può modificare lo stato interno della classe, verificare l'input). Quindi utilizzare exceptions per rendere il problema del chiamante se quell'input non è ben formato o se tale operazione violerà qualche invariante di classe.

+3

+1 da parte mia. Registra le cose meglio della mia risposta (ora cancellata). Non ho ancora avuto il mio caffè. –

0

Il controllo degli errori eseguito all'interno di una classe dovrebbe occuparsi delle possibilità in cui il metodo di quella classe non riuscirà. In altre parole, se la tua classe di numeri avesse un metodo di divisione, dovrebbe verificare che il denominatore non sia uno zero.

Il controllo degli errori eseguito sull'istanza di una classe (al di fuori della classe) dovrebbe richiedere di verificare che vengano restituiti i risultati corretti di una proprietà o di un metodo di classe. Dal momento che in genere questo non dovrebbe accadere con una classe ben progettata, di solito controlli i casi estremi.

Tuttavia, quando si inizia ad avere una classe che tiene traccia di più cose come il tuo caso, normalmente separerei ulteriormente la classe. Crea delle classi per gestire le tue funzioni matematiche e poi fai in modo che la classe dei numeri usi quelle classi matematiche. In questo modo hai una migliore separazione tra preoccupazioni, codice più ordinato e test più semplici.

+0

dovresti quindi invitare la mia risposta. per quel poco che ho fatto, ho sicuramente aggiunto degli assegni per ogni possibile cosa che potesse andare storta (eccetto cose folli come la mancanza di memoria). –

0

Personalmente, starei lontano da quello che stai cercando di fare nel costruttore nel secondo esempio. È difficile implementare i codici e viola lo information hiding principal. In caso contrario, senza sapere ciò che la classe fa internamente, quando lo fai $num = new Number(8);, è difficile capire perché stai ricevendo 47 indietro ... Viola anche il no magic number principal ...

Per quanto riguarda i metodi, si guardano bene a me. In questi casi potresti voler lanciare un'eccezione o restituire un valore booleano. Quello che scegli è un fattore molto più di quello che viene discusso qui (come le tue preferenze, che cosa fa esattamente la classe, convenzioni, ecc ...)

Oh, e hai qualche problema di loop infinito in la tua classe.function number() dovrebbe essere:

function number() { 
    return $this->number; 
} 

e lo stesso per error() ...

Problemi correlati