È questo il modo "corretto" di fare le cose o dovremmo installare la classe di utilità come e quando ne abbiamo bisogno?
Dal punto di vista OOD dipende :-)
Per pure functions si dovrebbe usare metodi statici in Java/C#. In C# puoi anche provare a utilizzare i metodi di estensione come altri descrivono.
Per i metodi di utilità che non sono funzioni pure (ad esempio la lettura di alcuni file), è necessario creare un'istanza per migliorare la testabilità (ad esempio, consentire il mocking).
La differenza è che questi ultimi, sebbene non mantengano uno stato direttamente, comunicano con alcuni componenti esterni che possiedono uno stato, eventualmente modificabile. Questo stato esterno può far sì che questo metodo di utilità restituisca risultati diversi nel tempo (per lo stesso input) rendendo molto più difficile testare e ragionare. È un buon principio di progettazione distinguere tra funzioni pure e tali metodi di utilità ponendo quest'ultimo come metodo di istanza esplicito.
Tuttavia, nella pratica Java, "l'argomento di simulazione" di solito prende la precedenza, poiché non consente di simulare i metodi statici.
Non sarei preoccupato per la differenza di memoria tra una classe statica e la creazione di un'istanza. Se non ci sono campi di classe (che sembra non esserci) occuperà solo una manciata di byte per istanza attiva della classe. –