Adoravo le classi di utilità riempite con metodi statici. Fecero un grande consolidamento dei metodi di aiuto che altrimenti sarebbero dovuti causare ridondanza e inferno di manutenzione. Sono molto facili da usare, nessuna istanza, nessuno smaltimento, solo il fuoco e lo scordo. Immagino che questo sia stato il mio primo inconsapevole tentativo di creare un'architettura orientata ai servizi - molti servizi senza stato che hanno fatto il loro lavoro e nient'altro. Man mano che cresce un sistema, tuttavia, arrivano i draghi.
Polimorfismo
Supponiamo di avere il metodo UtilityClass.SomeMethod che ronza felicemente. All'improvviso dobbiamo modificare leggermente la funzionalità. La maggior parte delle funzionalità è la stessa, ma dobbiamo comunque cambiare un paio di parti. Se non fosse stato un metodo statico, avremmo potuto creare una classe derivata e modificare i contenuti del metodo secondo necessità. Essendo un metodo statico, non possiamo. Certo, se abbiamo solo bisogno di aggiungere funzionalità prima o dopo il vecchio metodo, possiamo creare una nuova classe e chiamare quella vecchia al suo interno - ma è semplicemente grossolano.
Problemi di interfaccia
I metodi statici non possono essere definiti tramite interfacce per motivi logici. E poiché non possiamo ignorare i metodi statici, le classi statiche sono inutili quando dobbiamo passarle in giro dalla loro interfaccia. Questo ci rende incapaci di usare le classi statiche come parte di un modello di strategia. Potremmo correggere alcuni problemi passando delegati anziché interfacce .
Test
Fondamentalmente questo va di pari passo con i problemi dell'interfaccia menzionati sopra. Poiché la nostra capacità di scambiare le implementazioni è molto limitata, avremo anche problemi a sostituire il codice di produzione con il codice di prova. Ancora una volta, possiamo racchiuderli ma ci richiederà di modificare grandi parti del nostro codice solo per poter accettare wrapper invece degli oggetti reali.
Favorisce i BLOB
Poiché i metodi statici vengono generalmente utilizzati come metodi di utilità e i metodi di utilità di solito hanno scopi diversi, finiremo rapidamente con una grande classe piena di funzionalità non coerente - idealmente, ogni classe dovrebbe avere un unico scopo all'interno del sistema . Preferirei avere un numero di lezioni cinque volte maggiore se i loro scopi sono ben definiti.
Creep di parametro
Per cominciare, quel piccolo metodo statico carino e innocente potrebbe prendere un singolo parametro. Man mano che la funzionalità aumenta, vengono aggiunti un paio di nuovi parametri. Presto verranno aggiunti ulteriori parametri che sono facoltativi, quindi creiamo sovraccarichi del metodo (o semplicemente aggiungiamo valori predefiniti, nelle lingue che li supportano). In poco tempo, abbiamo un metodo che accetta 10 parametri. Sono richiesti solo i primi tre, i parametri 4-7 sono opzionali. Ma se viene specificato il parametro 6, è necessario compilare anche 7-9 ... Se avessimo creato una classe con il solo scopo di fare ciò che ha fatto questo metodo statico, potremmo risolverlo prendendo i parametri richiesti nel costruttore e consentire all'utente di impostare valori opzionali tramite proprietà o metodi per impostare più valori interdipendenti contemporaneamente. Inoltre, se un metodo è diventato così complesso,
Consumatori esigenti di creare un'istanza di classi senza motivo
Uno degli argomenti più comuni è, perché chiedere ai consumatori della nostra classe di creare un'istanza per invocare questo singolo metodo, senza averne successivamente bisogno? La creazione di un'istanza di una classe è un'operazione molto economica nella maggior parte delle lingue, quindi la velocità non è un problema. L'aggiunta di una riga aggiuntiva di codice al consumatore è un costo basso per porre le basi di una soluzione molto più sostenibile in futuro. Infine, se si desidera evitare la creazione di istanze, è sufficiente creare un wrapper singleton della propria classe che consenta un facile riutilizzo, sebbene ciò richieda che la classe sia apolide. Se non è stateless, è comunque possibile creare metodi wrapper statici che gestiscono tutto, offrendo comunque tutti i vantaggi a lungo termine. Finalmente,
Solo un Sith si occupa di assoluti
Naturalmente, ci sono eccezioni alla mia antipatia per i metodi statici. Le vere classi di utilità che non comportano alcun rischio di gonfiamento sono casi eccellenti per metodi statici, come System.Convert. Se il tuo progetto è unico e non richiede requisiti per la manutenzione futura, l'architettura complessiva non è davvero molto importante - statica o non statica, non importa - la velocità di sviluppo è comunque importante.
Standard, standard, standard!
L'uso dei metodi di istanza non impedisce di utilizzare anche metodi statici e viceversa. Finché c'è un ragionamento dietro la differenziazione ed è standardizzata. Non c'è niente di peggio che guardare un livello aziendale tentacolare con diversi metodi di implementazione.