Evitare il boilerplate nelle classi PHP

3

Sto lavorando su un codice PHP e man mano che cresce mi stanco sempre di ripetere lo stesso modello standard ancora e ancora e ancora:

class BolerPlate
{
    protected $property1;
    protected $property2;
    ...

    public function __construct ($property1, $property2, ...)
    {
        $this->property1 = $property1;
        $this->property2 = $property2;
        ...
    }
}

Quindi sto ri-digitando qui ogni nome di proprietà 4 (!) volte solo per ottenere la configurazione standard! In ogni classe! Non sembra elegante né ASCIUTTO per me. E riprovare gli stessi nomi crea più opportunità di bug.

Mi chiedo se ci sia un modo più elegante o le migliori pratiche per ottenere la stessa impostazione con un codice più facile per gli occhi:)

EDIT. Quello che ho in mente è una sorta di metodo di fabbrica in cui posso fornire l'elenco delle proprietà solo una volta ciascuna. O utilizzando variabili variabili e iterate su tutte le proprietà?

    
posta Dmitri Zaitsev 30.08.2013 - 15:05
fonte

3 risposte

2

In breve: Tratti potrebbe essere la funzione che stai cercando.

Un tratto è la soluzione di PHP 5.4 per la mancanza di ereditarietà multipla nella lingua e un modo per evitare catene ereditarie gerarchiche. Un altro modo per pensarci è che includere i tratti nelle tue classi è un modo pulito per mantenere il tuo codice a secco senza infrangere i buoni principi di progettazione.

Un modo ancora più semplice di pensarci è: Ehi, tutto quel codice della piastra della caldaia che hai copiato e incollato ovunque, ma ora vuoi cambiare qualcosa? bene sostituirlo con un tratto e chiamarlo un giorno.

Ecco alcuni esempi e un buon post su questo argomento .

    
risposta data 30.08.2013 - 15:24
fonte
0

Ecco alcune possibili soluzioni alla mia domanda ispirate a questo risposta . Nella sua forma più pigra sembra così:

public function __construct ($propertyArray) {
    foreach ($propertyArray as $property) {
        $this->$property = $property;
    }
}

Quindi si passano tutti gli argomenti come array e quindi il codice diventa uniforme e può essere ereditato da. Devi ancora scrivere manualmente l'elenco delle variabili protette poiché il seguente (purtroppo) non funziona:

    foreach ($propertyArray as $property) {
        protected $property; // or private $this->property
    }

e sembra non esserci un modo semplice per aggirare :(. Il vero problema qui, molto peggio di poche righe in più da digitare, è la conseguenza di errori di stampa, che possono portare alla creazione di proprietà private errate, mentre le proprietà corrette dell'array diventano pubbliche contro l'intenzione di dev.

Lo stesso problema colpisce in realtà anche il modo tradizionale originale.

Una soluzione parziale è usare il trucco ispirato alla risposta citata:

public function __construct ($propertyArray) {
    foreach ($propertyArray as $property) {
        $prefixedProperty = 'prefix' . ucfirst(strtolower($property));
        $this->$prefixedProperty = $property;
    }
}

Quindi nascondi la proprietà aggiungendo 'prefix' al suo nome, la cosiddetta sicurezza per oscurità :). Ora la proprietà è ancora pubblica in caso di errore di stampa, ma speri di non colpirlo così facilmente. Ancora non al 100% a prova di proiettile.

Ora ecco la soluzione migliore che ho trovato:

class BulletProof {
    protected $myProperty = '';

    public function __construct ($propertyArray) {
        foreach ($propertyArray as $property) {
            if (! isset($this->$property) ) {
               throw new exception("Careful, buddy! You either forgot or mistyped your declaration of $property!";
            }
            $this->$property = $property;
        }
    }        
}

Quindi se hai fatto un errore di digitazione o hai dimenticato di dichiarare la variabile, il compilatore ti avvisa con un'eccezione! Per farlo funzionare, devi inizializzare tutte le tue variabili con qualcosa di diverso da null , che non è troppo oneroso, dato che sono state sovrascritte dal costruttore.

Se qualcuno conosce un modo più elegante, sarei felice di imparare.

In un'altra nota sono grato a Yannis Rizos per i suoi suggerimenti nella chat privata, che implicano l'uso metodi magici __set e __get , sempre con la conseguenza che le proprietà diventano pubbliche.

    
risposta data 15.09.2013 - 22:06
fonte
0

Prima di tutto, capisco il tuo dolore. Se si utilizzano gli spazi dei nomi, aggiungere un'istruzione use e digitare hint per qualsiasi dipendenza di classe portando il totale a sei.

Variabili variabili o qualsiasi altro hackery potrebbe farti risparmiare un po 'di massa ora, ma ti danneggerà nel lungo periodo. I tratti presumono che stai riutilizzando il codice, che probabilmente non è il caso, o almeno non lo sarà ogni volta.

La cosa migliore che puoi fare è minimizzare le dipendenze per classe e cercare di impedire che le cose sfuggano di mano. Puoi usare macro, modelli o qualsiasi altra cosa tu voglia chiamarli per scriverli solo una volta per dipendenza. Questo aiuta con i tasti, ma il codice risultante sarà ancora ripetitivo.

Siamo spiacenti, questo è lo stato attuale di PHP.

    
risposta data 08.10.2013 - 01:06
fonte