Is this generally bad because of its dependency ?
Non esiste una regola di cattiva pratica inerente che è stata violata qui. Se non altro, le dipendenze sono il primo passo nella giusta direzione (quando si inizia da un singolo metodo monolitico).
Non ci sono problemi reali qui, a condizione che questo metodo statico soddisfi i criteri per essere un metodo statico . I criteri principali sono:
- Il metodo statico non si basa su uno stato interno e fa affidamento solo sui parametri del metodo che gli vengono forniti.
- L'operazione rappresentata dal metodo statico è globalmente corretta e non specifica per il contesto.
Questo sembra essere il caso del tuo codice, quindi non ci sono problemi.
Is there a cleaner way of doing this so the class is less dependant?
Non come una regola globale senza un particolare contesto dato. Nei casi determinati , può essere giustificato utilizzare un'interfaccia e un'iniezione di dipendenza, ma non è il caso del codice. Elaborerò le differenze.
Quando utilizzare i metodi statici:
In base al metodo statico, deduco che il metodo è universalmente corretto e che non ci sarà mai un "metodo concorrente" diverso dal metodo originale ma funzionalmente equivalente.
Ad esempio:
public static int AddNumbers(int a, int b)
{
return a + b;
}
Questo è universalmente corretto, e quindi dovrebbe essere un metodo statico.
Quando utilizzare l'iniezione delle dipendenze:
Supponiamo che tu stia facendo affidamento su una fonte esterna (ad esempio Google) per eseguire il calcolo:
public static int AddNumbers(int a, int b)
{
return Google.Query($"{a} + {b}");
}
Inizialmente, potresti rendere questo un metodo statico, poiché vuoi che questa sia la tua unica risorsa esterna. Tuttavia, dovresti identificare che è possibile che Google sia offline, o forse addirittura interrompere il servizio di calcoli matematici.
Vuoi che la tua applicazione sia in grado di interrogare altre risorse quando non puoi più fare affidamento su Google. Quindi diciamo che usi WolframAlpha come backup. Poiché ora hai due opzioni concorrenti ma funzionalmente equivalenti , non puoi renderle dei metodi statici.
Bene, potresti:
public static int AddNumbersViaGoogle(int a, int b)
{
return Google.Query($"{a} + {b}");
}
public static int AddNumbersViaWolframAlpha(int a, int b)
{
return WolframAlpha.Add(a, b);
}
... ma sarebbe cattiva pratica .
Invece, crei un'interfaccia e quindi inserisci la dipendenza corretta nella tua classe:
public interface INumberAddition
{
int Add(int a, int b);
}
L'interfaccia stipula il contratto che entrambi i gestori di Google e WolframAlpha devono seguire.
public class GoogleAdder : INumberAddition
{
public int Add(int a, int b)
{
return Google.Query($"{a} + {b}");
}
}
public class WolframAlphaAdder : INumberAddition
{
public int Add(int a, int b)
{
return WolframAlpha.Add(a, b);
}
}
Quindi modifica la classe per ricevere qualsiasi oggetto che implementa INumberAddition
:
public class Calculator
{
private readonly INumberAddition _additionHandler;
public Calculator(INumberAddition additionHandler)
{
_additionHandler = additionHandler;
}
public int FindOutWhatOnePlusOneIs()
{
return _additionHandler.Add(1,1);
}
}
In questo modo, scegli la tua dipendenza a un livello superiore:
var googleCalculator = new Calculator(new GoogleAdder());
var googleResult = googleCalculator.FindOutWhatOnePlusOneIs();
var wolframCalculator = new Calculator(new WolfranAlphaAdder());
var wolframResult = wolframCalculator.FindOutWhatOnePlusOneIs();
Il caso d'uso è molto semplificato, ma mostra l'intenzione principale: Calculator
può facilmente passare da una risorsa esterna all'altra quando necessario.
Riassunto
Se ragionevolmente si aspetta che la tua logica sia universalmente vera e non debba mai essere sostituita, allora è sufficiente un metodo statico.
Se ragionevolmente si aspetta che la dipendenza venga scambiata a un certo punto, o se si desidera ridurre al minimo le modifiche al codice, è necessario che una dipendenza sia scambiata inaspettatamente; quindi è meglio iniettare la dipendenza utilizzando un'interfaccia in modo da poterlo sostituire facilmente senza dover modificare gran parte del codice.