Seguire l'OCP dovrebbe essere sempre uno degli obiettivi di un programmatore OOP. Ignorare questo principio erode quanto è utile decomporsi in oggetti.
È eccezionalmente pigro pensare: "Beh, se vogliono reagire al cambiamento possono semplicemente riscriverlo".
OCP ti chiede di favorire un design che permetta il cambiamento aggiungendo un nuovo codice piuttosto che cambiando il vecchio codice.
I meccanismi strutturali per questo possono essere complessi come un modello di progettazione o semplici come introdurre una variabile. L'astrazione funziona al meglio quando non riesci a vedere i dettagli che stai utilizzando.
Il problema più eloquente è quando ritieni opportuno separare un'idea da un'altra inserendole in oggetti diversi, ma l'UNO sa esattamente quale implementazione dell'altro sta parlando. Fare ciò non solo viola l'OCP, ma significa che hai digitato una classe extra senza una buona ragione. Se si separano le idee in oggetti diversi, non dovrebbero tenersi reciprocamente in una presa mortale.
Tuttavia, il cambiamento è difficile da prevedere. Yagni ci insegna a non creare cose che potrebbero essere utili, solo cose che sono utili oggi.
Piuttosto che predire il futuro, sii prudente quando si assume che qualcosa sarà stabile. Le nostre astrazioni di alto livello, le nostre interfacce, ci feriscono davvero quando cambiano. Mantenere ciò che assumono essere al minimo stabile. Spingi ciò che non sei sicuro di scendere ai livelli più bassi. Spezzali per mantenere la loro vulnerabilità a cambiare l'impronta di piccole dimensioni. Lascia che servano solo un master.
Fai questo e seguire l'OCP non dovrebbe essere troppo diverso. Se, però, impazzisci le interfacce su ogni oggetto e rifiuti di chiamare qualsiasi cosa che non sia polimorfica, beh, ci stai dando un pessimo nome ai codificatori di OOP.
Il miglior consiglio che potresti applicare qui era in realtà su quando reagire a una violazione di DRY. È molto più probabile che si decompongano correttamente la seconda volta che ti ripeti, quindi sei la prima volta. Quindi forse non essere così pronto a reagire.
Questa saggezza dovrebbe attenuare quanto sei veloce nel prevedere il cambiamento. I test unitari ci aiutano a vedere come possiamo modificare i dettagli di implementazione. Mentre questo è un buon test di unità di esercizi strutturali non è il codice di produzione. Stai attento a pensare che ti mostrano come cambieranno le cose.
Ma dovresti sentirti male ogni volta che aggiungi una funzione o correggi un bug modificando il codice esistente. Anche se in realtà non hai client esterni indipendenti, è davvero bello poter supportare grandi quantità di codice come se lo fosse.
Ricorda, questi principi non ti aiuteranno a far funzionare il tuo codice più velocemente. Ti aiutano a mantenere il tuo codice funzionante una volta fatto. Perciò non scoprirai se stai sprecando il tuo tempo facendo sforzi per seguirli fino a quando i cambiamenti cominciano ad arrivare. Se vuoi esercitarti ad applicarli, non puoi semplicemente codificare su una specifica fissa. Devi codificare su una specifica mutevole che ti sorprende.
Un modo conservativo per applicare questi principi è aggiungere complessità in reazione al cambiamento piuttosto che in previsione. Quando prenderò questo trattato mi perdonerò per aver dovuto cambiare il codice esistente in un modulo una volta, forse due volte. Dopodiché è il momento di vedere come impedire che accada di nuovo.
Altrimenti, potremmo anche tornare alla programmazione procedurale perché anche se è in grado di riscrivere ogni volta, può gestire il cambiamento.