Domanda

che sto cercando di progettare una domanda in seguito intuizioni Misko Heverys . Si tratta di un esperimento interessante e una sfida. Attualmente sto lottando con la mia implementazione ViewHelper.

Il ViewHelper disaccoppia il modello dalla vista. Nella mia implementazione avvolge il modello e fornisce le API per la visualizzazione da utilizzare. Sto utilizzando PHP, ma spero l'implementazione è leggibile per tutti:

class PostViewHelper {
    private $postModel;

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

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

Nel mio modello (vista) file di questo potrebbe essere chiamato in questo modo:

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

Fin qui tutto bene. Il problema che ho è quando voglio allegare un filtro ai ViewHelpers. Voglio avere i plugin che filtrano l'uscita del titolo call (). Il metodo sarebbe diventato in questo modo:

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

Ho bisogno di osservatori in là, o un EventHandler, o qualsiasi servizio (in quello che vedo come un newable, quindi ha bisogno di essere passato attraverso la pila). Come posso fare questo seguendo i principi di Misko Hevery? Io so come posso fare questo senza di essa. Mi interessa come per posso prenderlo e attualmente non vedo una soluzione. ViewHelper potrebbe essere un iniettabile troppo, ma poi ricevendo il modello si pone il problema.

È stato utile?

Soluzione

Non ho trovato il post sul blog si fa riferimento molto interessanti o perspicace.

Quello che si sta descrivendo sembra più simile a un Decorator di ogni altra cosa a che fare con l'iniezione di dipendenza. iniezione di dipendenza è come si preparano da grafi di oggetti, non la loro Stato , una volta costruito.

Detto questo, io suggerirei di prendere il vostro modello Decorator e correre con esso.

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";
    }
}

Si potrebbe semplicemente utilizzare qualsiasi quadro DI devi costruire questo grafico oggetto in questo modo:

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

Io uso spesso questo approccio quando si costruisce oggetti nidificati complessi.

Un problema che si potrebbe incorrere in si definisce "troppi" funzioni nel PostInterface. Può essere un dolore di dover attuare tali in ogni classe decoratore. Approfitto delle funzioni magiche di PHP per ottenere intorno a questo.

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);
    }
}

Con questo tipo di decoratore in uso, posso ignorare selettivamente qualsiasi metodo che ho bisogno di fornire la funzionalità decorato. Tutto ciò che non sostituiscono viene passato al l'oggetto sottostante. decorazioni multipli possono verificarsi tutto mantenendo l'interfaccia dell'oggetto sottostante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top