Question

Je suis en train de concevoir une application suivante aperçus Misko Heverys . Il est une expérience intéressante et un défi. À l'heure actuelle, je me bats avec ma mise en œuvre de ViewHelper.

Le ViewHelper découple le modèle de la vue. Dans ma mise en œuvre, il enveloppe le modèle et fournit l'API pour la vue d'utiliser. J'utilise PHP, mais j'espère que la mise en œuvre est lisible pour tout le monde:

class PostViewHelper {
    private $postModel;

    public function __construct(PostModel $postModel) {
         $this->postModel = $postModel;
    }

    public function title() {
         return $this->postModel->getTitle();
    }
}

Dans mon modèle (vue) déposer ce qui pourrait être appelé comme ceci:

<h1><?php echo $this->post->title(); ?></h1>

Jusqu'à présent, si bon. Le problème que j'ai est quand je veux fixer un filtre aux aides de vue. Je veux avoir des plugins qui filtrent la sortie de l'appel de titre (). La méthode deviendrait comme ceci:

public function title() {
    return $this->filter($this->postModel->getTitle());
}

Je dois obtenir des observateurs là-dedans, ou un gestionnaire d'événements, ou quel que soit le service (dans ce que je vois comme newable, donc il doit être passé à travers la pile). Comment puis-je faire cela en suivant les principes de Misko Hevery? Je sais que je peux le faire sans elle. Je suis intéressé par la façon dont je peux le prendre et actuellement je ne vois pas une solution. ViewHelper pourrait être un injectable aussi, mais obtenir le modèle là est le problème.

Était-ce utile?

La solution

Je ne trouve pas le billet de blog que vous avez mentionné très intéressant ou perspicace.

Ce que vous décrivez ressemble plus à un décorateur que rien à voir avec l'injection de dépendance. L'injection de dépendance est comment vous construisez vos graphes d'objets, pas leur État une fois construit.

Cela dit, je suggère de prendre votre modèle de décorateur et courir avec lui.

interface PostInterface
{
    public function title();
}

class PostModel implements PostInterface
{
    public function title()
    {
        return $this->title;
    }
}

class PostViewHelper implements PostInterface
{
    public function __construct(PostInterface $post)
    {
        $this->post = $post;
    }

    public function title()
    {
        return $this->post->title();
    }
}

class PostFilter implements PostInterface
{
    public function __construct(PostInterface $post)
    {
        $this->post = $post;
    }

    public function title()
    {
        return $this->filter($this->post->title());
    }

    protected function filter($str)
    {
        return "FILTERED:$str";
    }
}

Vous souhaitez simplement utiliser quel que soit le cadre DI vous devez construire ce graphique d'objet comme ceci:

$post = new PostFilter(new PostViewHelper($model)));

J'utilise souvent cette approche lors de la construction des objets imbriqués complexes.

Un problème que vous pourriez rencontrer est la définition de « trop » fonctions dans votre PostInterface. Il peut être douleur d'avoir à mettre en œuvre ces derniers dans toutes les classes de décorateur. Je profite des fonctions magiques de PHP pour contourner cela.

interface PostInterface
{
    /**
     * Minimal interface. This is the accessor
     * for the unique ID of this Post.
     */
    public function getId();
}


class SomeDecoratedPost implements PostInterface
{
    public function __construct(PostInterface $post)
    {
        $this->_post = $post;
    }

    public function getId()
    {
        return $this->_post->getId();
    }

    /**
     * The following magic functions proxy all 
     * calls back to the decorated Post
     */
    public function __call($name, $arguments)
    {
        return call_user_func_array(array($this->_post, $name), $arguments);
    }

    public function __get($name)
    {
        return $this->_post->get($name);
    }

    public function __set($name, $value)
    {
        $this->_post->__set($name, $value);
    }

    public function __isset($name)
    {
        return $this->_post->__isset($name);
    }

    public function __unset($name)
    {
        $this->_post->__unset($name);
    }
}

Avec ce type de décorateur en cours d'utilisation, je peux passer outre sélectivement quelque méthode que je dois fournir la fonctionnalité décorée. Tout ce que je ne l'emporte pas sur est passé à l'objet sous-jacent. décorations multiples peuvent se produire tout en maintenant l'interface de l'objet sous-jacent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top