A seconda delle dipendenze

1
public class Connection : IConnection
{
    public Connection(Uri baseAddress, ISerializer serializer)
    {
        BaseAddress = baseAddress;

        Serializer = serializer;

        ResponseFactory = new ResponseFactory(serializer);
    }

    private Uri BaseAddress { get; set; }

    public IResponseFactory ResponseFactory { get; set; }

    private ISerializer Serializer { get; }
}

In questo codice (redatto per brevità), la classe Connection ha due dipendenze ottenute tramite l'iniezione del costruttore.

Ha una terza dipendenza, su IResponseFactory , in cui è disponibile l'iniezione di proprietà, ma viene creato un default tramite la riga ResponseFactory = new ResponseFactory(serializer) nel costruttore. Suppongo che la vista fosse che ResponseFactory è un "default locale" adatto, per usare la terminologia di Mark Seemann, ma un utente della classe Connection è libero di fornire un IResponseFactory alternativo se lo desiderano.

Nel rivisitare questo codice dopo un po 'di tempo, sono ambivalente riguardo alla creazione del default locale nel costruttore e alla sua dipendenza da ISerializer . Mentre ISerializer è richiesto a destra dalla classe Connection , 'concatenarlo' insieme a ResponseFactory sembra sbagliato. Sembra che la classe Connection debba richiedere un IResponseFactory tramite il costruttore e rinunciare alla praticità del default locale e alla sua dipendenza da ISerializer , che si verifica anche in questa classe.

Che ne pensi? Si tratta di un 'odore' definito?

    
posta David Osborne 04.04.2018 - 12:43
fonte

2 risposte

1

Sì, sembra un po 'strano per una serie di motivi.

  1. Mix di proprietà e iniezione del costruttore
  2. ISerializer è un vero requisito se è usato solo in ResponseFactory?
  3. Crea sempre un ResponseFactory anche se non è mai stato utilizzato?
  4. Cosa succede se cambio ResponseFactory a metà del ciclo di vita di Connection?

Declinazione di responsabilità standard "Odore di codice"

  • un 'odore di codice' indica solo un possibile problema, non significa che ci sia sicuramente un problema.
  • non possiamo vedere l'intero codice, forse in questo modo è necessario per qualche ragione
risposta data 04.04.2018 - 12:56
fonte
0

La domanda è: se ResponseFactory è necessario per fare qualcosa di significativo o meno.

YES? Quindi dovrebbe essere fornito tramite l'iniezione del costruttore. Da un lato, è bello, che il costruttore fornisce in qualche modo l'impostazione predefinita sensata . Ma dall'altra parte, l'iniezione del costruttore rende le cose esplicite .

NO? Quindi non è necessario un locale default . Un campo semplicemente non inizializzato sarebbe sufficiente - al costo di un controllo nullo. Quando non è necessario, e nel caso lo sia, ma è stato trascurato, dovrebbe esserci un segnale chiaro (diverso da un NPE) che il chiamante non ha fatto i compiti.

Per quanto riguarda la risposta di @ Ewan:

Mix of property and constructor injection

Non vedo alcun problema nel fornire le dipendenze necessarie tramite l'iniezione del costruttore, mentre quelle facoltative tramite l'iniezione setter.

    
risposta data 04.05.2018 - 18:33
fonte

Leggi altre domande sui tag