Il modello dell'adattatore è una buona soluzione per l'aggiunta di metodi?

4

In alcuni pacchetti di alto livello (che non possiedo) ho un'interfaccia di instradamento.

Ora questa interfaccia Route contiene i dettagli per una rotta specifica all'interno del mio sistema. Il pacchetto di alto livello non contiene un metodo per aggiungere get parametri al percorso, come /customers?a=b .

class CustomerRoute extends BaseRoute implements RouteInterface 
{
    public function __construct()
    {
        $this->setController(CustomerController::class);
        $this->setAction('index');
        $this->setUrl('/customers');
        $this->setType('get');
    }
 }

Voglio aggiungere un altro metodo; setGetParameters come per esempio in una nuova classe base:

public function setGetParameters(array $parameters)
{
    $this->parameters = $parameters;
    $this->setUrl($this->getUrl() . $this->buildQueryString($parameters));
}

protected function buildQueryString(array $parameters)
{
    return '?' . http_build_query($parameters);
}

Ma ciò violerebbe il Principio di sostituzione di Liskov. Se creo una dipendenza su RouteInterface , potrei non accedere a setGetParameters .

Come:

$route->setGetParameters([
    'a'=>'b'
]);
$route->getUrl();

Qual è il modo migliore per andare?

Ho preso in considerazione:

Modello adattatore (oggetto)

Ti piace così?

class RouteAdapter implements Contracts\RouteAdapter
{
    protected $route;

    public function __construct(RouteInterface $route)
    {
        $this->route = $route;
    }

    public function setGetParameters(array $parameters)
    {
        $this->parameters = $parameters;
    }

    //the route methods
    public function getUrl()
    {
        $this->route->getUrl() . '?' . http_build_query($this->parameters);
    }

    //... other methods from route 
}

Schema decoratore

Ma con decoratore (ereditarietà) l'interfaccia del percorso non può cambiare.

Vistor

Ma il visitatore è meglio utilizzato per diversi tipi di classi.

Che cosa faresti se non fosse il proprietario del pacchetto di alto livello e cosa faresti se lo facessi?

Cambieresti la classe base per aggiungere i metodi e anche cambiare la RouteInterface?

Aggiornamento 1

Estendere l'interfaccia a una soluzione?

Questo potrebbe non essere un modello di design specifico.

Così:

class Route extends NewAbstractRoute
{
   //...
}

abstract class RouteInterface //the original interface
{
    //....
}

abstract class NewAbstractRoute extends RouteInterface 
{
    public function setGetParameters(array $parameters);
}

class Implementation extends NewAbstractRoute
{/*..*/}

In questo modo non violerebbe il principio substition Liskov per il pacchetto e posso fare una dipendenza alla nuova interfaccia.

Ma questa soluzione potrebbe non essere buona dal momento che è meglio non usare l'ereditarietà per aggiungere metodi, dal momento che potrebbe crea troppi sottosistemi.

    
posta Stefan 10.03.2017 - 10:27
fonte

1 risposta

1

Il punto di dire che un po 'di codice segue uno schema è quello di comunicare l'intento del codice. L'intento di un adattatore è di fare la stessa cosa in un modo diverso per rendere compatibile incompatibile. Un adattatore si trova tra due oggetti che devono comunicare e consente loro di lavorare senza dover cambiare il modo in cui comunicano.

L'esposizione di un nuovo metodo che aggiunge una nuova funzione non fa nulla di tutto ciò.

Estendere l'interfaccia è un modo migliore per descrivere quello che stai facendo. Niente in precedenza richiedeva questa interfaccia estesa. Ora sei libero di creare cose che possono usarlo.

La differenza qui non ha nulla a che fare se quello che hai fatto è stata una buona soluzione. I pattern non dovrebbero dettare il tuo design. Sono semplicemente un modo per comunicare quello che stai facendo.

    
risposta data 10.03.2017 - 14:00
fonte

Leggi altre domande sui tag