2012-01-03 2 views
5

È consigliabile utilizzare l'overloading solo per ragioni di denominazione di funzioni carine? :)Sovraccarico di proprietà e metodi in PHP: qual è la ragione?

Ad esempio:

echo $store->product->getPrice($currency);

  • product chiamerà __get poi __getObject ('prodotto'), che fa la roba Magik e restituisce il prodotto corrente che viene visto come un oggetto (è istanziato se è la prima chiamata)

echo $store->product('dog')->getPrice($currency);

  • qui product chiamerà __call, quindi __callObject ('prodotto', ...) ...


L'alternativa senza sovraccaricare sarebbe:

if(!$store->product) 
    $store->product = new Product(); 

echo $store->product->getPrice($currency); 

e

$product = new Product('dog'); 
echo $product->getPrice($currency); 

Mi piace molto il sovraccarico perché posso ottenere API belle per le mie lezioni. Ma il lato negativo è che roba sovraccaricata è 15 volte più lenta di chiamare direttamente proprietà/metodi.

È corretto utilizzare un sovraccarico come questo?

Nella mia applicazione corrente non chiamo membri sovraccaricati più di 1000 volte. E questo non dovrebbe avere così tanto impatto sulle prestazioni. Forse 0,1 secondi in più, che considerando che un sito viene solitamente generato in 0,5 - 1s non è tanto

+0

Il sovraccarico di prestazioni in questo pezzo di codice non sembra che significativo. Ma in genere ho paura di usare molti metodi __call e __get (presumendo che lo userai per il resto del tuo software) – TFennis

+1

Se l'intera API si basa su Metodi Magici l'impatto sulle prestazioni potrebbe essere significativo e c'è un molte persone che non amano il codice magico perché fa cose non ovvie. – Gordon

risposta

3

È consigliabile utilizzare l'overloading solo per motivi di denominazione di funzioni carini? :)

No. Voglio dire, dipende. :) Aggiungiamo un po 'di suggestione e di carineria alla nostra vita di programmazione:

$ordinary = new stdClass(); 
$ordinary->Caption = 'Hello'; 

class Awesome 
{ 
    private $ordinary; 
    public function __construct($ordinary) { 
     $this->ordinary = (array) $ordinary; 
    } 
    public function __get($name) { 
     $value = ''; 
     return $this->ordinary[$name]; 
    } 
} 

class Lovely extends Awesome 
{ 
    public function __get($name) 
    { 
     return '<3 ' . parent::__get($name) . ' <3'; 
    } 
} 

devo ammettere, l'esempio potrebbe essere un po' sopra le righe, ma viene mostra qualcosa.

Prima di tutto, l'ipotesi è che l'API sia per una classe. Quindi inizia con un ordinario stdClass.

Che l'esempio mostra quindi è che quelle funzioni magiche possono essere utilizzate per sovraccarico o decorare qualcosa. Può, ma non deve. Vedere l'API impressionante, è solo impressionante di per sé:

$awesome = new Awesome($ordinary); 

echo $awesome->Caption, "\n"; # This caption is just awesome by itself! 
# Hello 

e poi vedere il più bel esempio API:

$lovely = new Lovely($ordinary); 

echo $lovely->Caption, "\n"; # This caption is lovely, hughs and kisses everyone! 
# <3 Hello <3 

Quindi in questo esempio, è una buona idea per Lovely ma è inutile per Awesome, perché Awesome in realtà è molto più facile da ottenere:

$awesome = $ordinary; 

il che mi porta al punto, che il sovraccarico di un'API può onl essere utile fino a un punto specifico Come mostra Lovely, può essere usato per decorare un altro oggetto (non molto specificato), ma mostra anche che questo è solo una volta: Lovely ha già bisogno di sapere come chiamare Awesome per utilizzare la sua funzionalità usando (ora non magia più) __get metodo:

public function __get($name) 
    { 
     return '<3 ' . parent::__get($name) . ' <3'; 
    } 

Quando la società considera che Awesome è la vostra API, si può vedere che esso stesso ha impedito di essere in grado di essere sovraccaricato facilmente dagli altri coderette che vuole fare uso di esso .

Quindi il sovraccarico può andare bene nel codice concreto e l'API non dovrebbe impedirlo. Ma quando l'API è sovraccaricata, le cose possono rivelarsi difficili.

Non solo per la codifica, l'aggiunta di dinamiche/magia rende le cose difficili anche per il debug. Quindi, meglio rimanere chiaro per le API che crei e fornire interfacce più specifiche quindi solo [] o ->. È possibile dare alle cose nomi concreti e che funziona bene;)

Ed è molto più bella poi:

echo $store->getObject('product')->getPrice($currency); 
3

Lo svantaggio del sovraccarico è che devi descrivere tu stesso la "bella API", perché gli strumenti di documentazione non possono capire, cosa fai dentro i tuoi metodi Un altro punto è che spesso è "troppa magia": rendi il tuo codice molto più difficile capire la magia che realizzi.

Dall'altro lato non vedo alcun problema con la tua alternativa. È ancora più pulito nei miei occhi.

sidenote: evitare l'uso di doppi caratteri di sottolineatura all'inizio dei metodi, a condizione che non vengano implementati metodi magici.

1

I profitti derivano dai vantaggi offerti dal rispetto dei principi di progettazione orientata agli oggetti. Il primo esempio consente l'accoppiamento lento generando l'oggetto prodotto da una fabbrica. Per ulteriori informazioni sui principi di progettazione OO, vedere S.O.L.I.D. and G.R.A.S.P.