Un tratto dovrebbe riferirsi ai metodi padre?

4

È un odore di codice se i metodi nel mio tratto si riferiscono ai metodi parent:: o ai metodi che si presume siano nella classe di utilizzo?

Un esempio casuale (senza senso)

trait foo
{
    public function bar()
    {
        return parent::bar() . 'baz';
    }

    public function format($text)
    {
        $format = true;
        return $this->parse($text, $format);
    }
}

Questi metodi devono essere spostati nell'implementazione classe ?

Dovrei avere esclusivamente metodi senza dipendenze, all'interno di un tratto ?

    
posta Kamafeather 17.05.2018 - 11:22
fonte

2 risposte

5

Sì, è un odore di codice. Se un tratto è usato per rendere il codice più portabile, allora questo genere di cose lo rende meno portabile. Non dovresti farlo. Senza avere un esempio più concreto, sembra che quello che dovresti fare sia mettere il metodo di una barra in astratto e estenderlo. Questo approccio evita il potenziale bug di runtime in cui il tratto viene aggiunto a una classe che non ha la barra.

    
risposta data 17.05.2018 - 17:59
fonte
3

Va bene se un tratto dipende dai metodi della classe in cui è incorporato. Ma queste dipendenze dovrebbero essere esplicite, dichiarando un abstract function . PHP può quindi verificare che tale metodo esista effettivamente.

Ma i tratti non dovrebbero sovrascrivere i metodi. Questo è un comportamento piuttosto confuso. Invece, dai un nome diverso ai metodi nel tratto. In questo particolare esempio, ci si basa su un metodo nella classe base della classe in cui è incorporato il tratto. Questa è una dipendenza molto oscura. Confronta gli esempi di precedenza nei documenti .

Perché non usare invece le classi astratte? Perché puoi avere più tratti, ma solo una classe base. Pertanto, i tratti sono più generali e sono utili per un insieme di funzioni di convenienza che si desidera utilizzare in più classi. Il tuo metodo format è un ottimo esempio di questo. Scritto più chiaramente, sarebbe:

trait Formatter
{
    abstract public function parse($text, $format);

    public function format($text)
    {
        $format = true;
        return $this->parse($text, $format);
    }
}
    
risposta data 18.05.2018 - 22:56
fonte

Leggi altre domande sui tag