L'app di Laravel :: make () dovrebbe essere considerata una dipendenza?

0

Penso che la domanda in generale sia riassunta nel modo migliore in quanto l'App :: make () di Laravel può essere considerata una dipendenza? Da un lato può istanziare qualsiasi numero di diverse implementazioni, quindi forse non è una dipendenza difficile. D'altra parte, una classe dovrebbe essere realmente responsabile di chiamare App :: make () per creare un'istanza delle sue dipendenze, o sarebbe meglio farle passare come parametri alla classe? Qual è l'approccio più pulito / più SOLIDO?

Ecco un esempio specifico:

Un'app effettua una richiesta API a un server esterno. Una classe gestisce la richiesta HTTP effettiva che implementerà HttpClientInterface e una classe effettua la richiesta e recupera / analizza i dati, chiamandoli LookUp . Infine, una classe di servizio è in definitiva responsabile della chiamata di lookUp()  metodo su LookUp class.

Sto cercando di pensare al modo migliore per farlo.

Opzione 1 :

Crea un'istanza delle dipendenze nella classe di servizio e passale come parametri:

class LookUpService
{
    public function lookUp($identifier)
    {
        $client = App::make(HttpClientInterface::class);
        $provider = new LookUp($client);

        $results = $provider->lookUp($identifier);
    }
}

Opzione 2 :

In alternativa, dal momento che utilizziamo comunque l'app :: make () di Laravel, potremmo nasconderlo all'interno della classe LookUp.

class LookUpService
{
     public function lookUp($identifier)
     {
         $provider = new LookUp();
         $results = $provider->lookUp($identifier);
     }
}

class LookUp
{
     public function __construct()
     {
         $this->client = App::make(HttpClientInterface::class);
     }
}

Quale è meglio?

    
posta tam5 25.03.2016 - 14:45
fonte

1 risposta

1

Dovresti cercare di rendere il provider che implementa un'interfaccia che viene passata al costruttore del servizio. Il tuo servizio dovrebbe avere una proprietà privata che sarà l'interfaccia e nel costruttore assegnerai il tuo argomento alla proprietà. In questo modo puoi in seguito prendere in giro la tua classe e fare test unitari. Non conosco bene PHP, quindi scriverò qui un codice imitato:

class LookUpService implements LookUpServiceInterface
{
    private ProviderInterface $_provider
    public function __constructor(ProviderInterface $provider)
    {
        $_provider = provider
    }
    public function lookUp($identifier)
    {
        $results = $_provider->lookUp($identifier);
    }
}

class LookUp implements ProviderInterface
{
    private HttpClientInterface _client
     public function __construct(HttpClientInterface client)
     {
         $_client = client;
     }
}

class Controller
{
    private LookUpServiceInterface _lookUpService;
    public function __construct()
    {
        _lookUpService = new LookUpService(new LookUp(App::make(HttpClientInterface::class)));
    }

    public function someFunction()
    {
        _lookUpService.lookUp("identifier")
    }
}

Inoltre, dovresti fare la stessa cosa con la classe LookUp. Dovrebbe prendere HttpClientInterface nel costruttore.

Crea un'istanza di tutte quelle classi nel controller (o ovunque tu chiami il servizio). Ciò assicura che le tue classi non dipendano l'una dall'altra e possano essere prese in giro usando interfacce e unità testate.

Opzione 1: Se lo fai in questo modo, non puoi prendere in giro il tuo servizio perché chiamerà sempre LookUp () e App: make ().

Opzione 2: Praticamente lo stesso problema dell'opzione 1. Desiderate assicurarvi che il vostro servizio, i repository e così uno usino le interfacce in modo da poterle facilmente prendere in giro o cambiare il livello della classe di implementazione sopra il servizio.

    
risposta data 25.03.2016 - 15:11
fonte

Leggi altre domande sui tag