Diciamo, ad esempio, che hai un'applicazione con una classe ampiamente condivisa chiamata User
. Questa classe espone tutte le informazioni sull'utente, il loro ID, nome, livelli di accesso a ciascun modulo, fuso orario ecc.
I dati dell'utente sono ovviamente ampiamente referenziati in tutto il sistema, ma per qualsiasi motivo, il sistema è impostato in modo tale che invece di passare questo oggetto utente in classi che dipendono da esso, stiamo semplicemente passando singole proprietà da esso.
Una classe che richiede l'id utente, richiederà semplicemente il GUID userId
come parametro, a volte potrebbe essere necessario anche il nome utente, quindi viene passato come parametro separato. In alcuni casi, questo viene passato ai singoli metodi, quindi i valori non vengono affatto mantenuti a livello di classe.
Ogni volta che ho bisogno di accedere a informazioni diverse dalla classe User, devo apportare modifiche aggiungendo parametri e laddove l'aggiunta di un nuovo sovraccarico non è appropriata, devo cambiare anche ogni riferimento al metodo o al costruttore della classe.
L'utente è solo un esempio. Questo è ampiamente praticato nel nostro codice.
Ho ragione nel pensare che si tratti di una violazione del principio Open / Closed? Non solo l'atto di cambiare le classi esistenti, ma di istituirle in primo luogo in modo che i cambiamenti diffusi saranno molto probabilmente richiesti in futuro?
Se abbiamo appena passato l' User
oggetto, potrei apportare una piccola modifica alla classe con cui sto lavorando. Se devo aggiungere un parametro, potrei dover fare dozzine di modifiche ai riferimenti alla classe.
Ci sono altri principi infranti da questa pratica? Inversione di dipendenza forse? Anche se non stiamo facendo riferimento a un'astrazione, esiste solo un tipo di utente, quindi non c'è alcuna reale necessità di avere un'interfaccia utente.
Esistono altri principi non SOLID violati, come i principi di base della programmazione difensiva?
Il mio costruttore dovrebbe apparire così:
MyConstructor(GUID userid, String username)
O questo:
MyConstructor(User theUser)
Modifica post:
È stato suggerito di rispondere alla domanda in "Pass ID o oggetto?". Questo non risponde alla domanda su come la decisione di andare in entrambi i modi influisca sul tentativo di seguire i principi SOLIDI, che è al centro di questa domanda.
I
in SOLID
? MyConstructor
sostanzialmente dice ora "Ho bisogno di un Guid
e un string
". Quindi perché non avere un'interfaccia che fornisce a Guid
e a string
, lasciare User
implementare quell'interfaccia e lasciare MyConstructor
dipendere da un'istanza che implementa quell'interfaccia? E se le esigenze di MyConstructor
cambiamento, cambiano l'interfaccia. - Mi ha aiutato molto a pensare alle interfacce per "appartenere" al consumatore piuttosto che al fornitore . Quindi pensa "come consumatore ho bisogno di qualcosa che faccia questo e quello" invece di "come fornitore posso fare questo e quello".