Questo viola almeno tre principi di programmazione orientata agli oggetti e potenzialmente un quarto.
In primo luogo, questo viola il Principio di Almostonment . Supponiamo di avere una documentazione per uno solo dei metodi, e dobbiamo dedurre ciò che fa l'altro. Primo:
// Reads words from a file
public void LoadWords(string)
// ???
public void LoadWords(IEnumerable<string>)
Sarebbe molto facile guardare il primo e pensare che il secondo dovrebbe leggere le parole da un elenco di file. Quello sarebbe un comportamento coerente. Tuttavia, non lo è. Ora il contrario:
// ???
public void LoadWords(string)
// Loads the IEnumerable of strings into words
public void LoadWords(IEnumerable<string>)
Ora sarebbe molto facile guardare il secondo, e pensare che il primo dovrebbe caricare una singola parola. Invece, avrei cercato errori IO o potenzialmente qualcosa di totalmente inaspettato (se la parola capita di abbinare un nome di file reale) se provassi ad usarlo come tale. Questo metodo è difficile da ragionare perché i comportamenti sono così diversi.
In secondo luogo, questo codice viola la Legge di Demeter . In un metodo, ora devo raggiungere e interagire con il file system, che è un oggetto totalmente non correlato a un livello completamente diverso di astrazione. Dove prima avevo a che fare con il filtraggio e il salvataggio delle parole, ora devo preoccuparmi del codice del file system. Devo sapere come arrivare al file system, aprire un file, leggere un file, chiudere un file, assegnare un token al contenuto del file, rilevare eventuali eccezioni a cui potrebbero incorrere, ecc. Questa non dovrebbe essere la responsabilità di questa classe, che indica che si tratta di una violazione del principio di responsabilità singola .
Infine, possiamo anche violare il principio Open-Closed . Supponiamo di dover sovraccaricare il metodo per leggere da un flusso di rete. Dobbiamo aprire questa classe per aggiungere la funzionalità aggiuntiva. Ciò aggrava anche le violazioni Demeter e SRP.
Se i metodi vengono denominati in modo più esplicito, iniziamo a filtrare i dettagli di implementazione della nostra classe. In questo caso, la ragione è che le responsabilità non dovrebbero trovarsi nella nostra classe. Dovremmo spingere quelle decisioni di implementazione ai clienti della classe. Ciò consente loro di prendere la decisione, come già stavano facendo, ma offre loro molta più flessibilità e controllo, alleviando al contempo la tua classe dal peso di gestire tutti quei dettagli internamente.
La risposta di back2dos mostra come ottenere ciò tramite il codice client.