Sebbene nel codice sottostante venga utilizzato un semplice acquisto di un singolo articolo in un sito di e-commerce, la mia domanda generale riguarda l'aggiornamento di tutti i membri dei dati per mantenere i dati di un oggetto sempre in uno stato valido.
Ho trovato "coerenza" e "stato è cattivo" come frasi pertinenti, discusse qui: link
<?php
class CartItem {
private $price = 0;
private $shipping = 5; // default
private $tax = 0;
private $taxPC = 5; // fixed
private $totalCost = 0;
/* private function to update all relevant data members */
private function updateAllDataMembers() {
$this->tax = $this->taxPC * 0.01 * $this->price;
$this->totalCost = $this->price + $this->shipping + $this->tax;
}
public function setPrice($price) {
$this->price = $price;
$this->updateAllDataMembers(); /* data is now in valid state */
}
public function setShipping($shipping) {
$this->shipping = $shipping;
$this->updateAllDataMembers(); /* call this in every setter */
}
public function getPrice() {
return $this->price;
}
public function getTaxAmt() {
return $this->tax;
}
public function getShipping() {
return $this->shipping;
}
public function getTotalCost() {
return $this->totalCost;
}
}
$i = new CartItem();
$i->setPrice(100);
$i->setShipping(20);
echo "Price = ".$i->getPrice().
"<br>Shipping = ".$i->getShipping().
"<br>Tax = ".$i->getTaxAmt().
"<br>Total Cost = ".$i->getTotalCost();
Eventuali svantaggi o forse modi migliori per farlo?
Si tratta di un problema ricorrente nelle applicazioni reali supportato da un database relazionale e, se non si utilizzano ampiamente le stored procedure, è necessario trasferire tutta la convalida nel database. Penso che l'archivio dati debba solo memorizzare i dati, mentre il codice dovrebbe fare tutto il lavoro di mantenimento dello stato di esecuzione.
EDIT: questa è una domanda correlata ma non ha una raccomandazione di best practice riguardante una singola grande funzione per mantenere uno stato valido: link
EDIT2: Sebbene la risposta di @ eignesheep sia la migliore, questa risposta - link - è ciò che riempie le linee tra @ La risposta di eigensheep e ciò che volevo sapere - il codice dovrebbe solo elaborare e lo stato globale dovrebbe essere sostituito dal passaggio di stato abilitato alla DI tra gli oggetti.