web-dev-qa-db-fra.com

Un trait doit-il faire référence aux méthodes parentales?

Est-ce une odeur de code si les méthodes de mon trait font référence à parent::méthodes ou méthodes supposées appartenir à la classe utilisatrice?

Un exemple aléatoire (insensé)

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

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

Ces méthodes doivent-elles être déplacées dans l'implémentation class?

Dois-je avoir exclusivement des méthodes sans dépendances, à l'intérieur d'un trait?

9
Kamafeather

C'est bien si un trait dépend des méthodes de la classe dans laquelle il est intégré. Mais ces dépendances doivent être explicites, en déclarant un abstract function . PHP peut alors vérifier qu'une telle méthode existe réellement.

Mais les traits ne doivent pas remplacer les méthodes. C'est un comportement assez déroutant. Au lieu de cela, donnez un nom différent aux méthodes du trait. Dans cet exemple particulier, vous comptez sur une méthode de la classe de base de la classe dans laquelle votre trait est intégré. C'est une dépendance très obscure. Comparez les exemples de priorité dans la documentation .

Pourquoi ne pas utiliser des classes abstraites à la place? Parce que vous pouvez avoir plusieurs traits, mais une seule classe de base. Par conséquent, les traits sont plus généraux et sont utiles pour un ensemble de fonctions pratiques que vous souhaitez utiliser dans plusieurs classes. Votre méthode format en est un excellent exemple. Plus clairement, ce serait:

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

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

Oui, c'est une odeur de code. Si un trait est utilisé pour rendre le code plus portable, alors ce genre de chose le rend moins portable. Tu ne devrais pas le faire. Sans avoir un exemple plus concret, il semble que ce que vous devriez faire est de mettre cette méthode de barre dans un résumé et de l'étendre. Cette approche évite le bogue d'exécution potentiel où le trait est ajouté à une classe qui n'a pas de barre.

7
zquintana