Els principis SOLID són fonamentals en el desenvolupament de programari orientat a objectes. Aquests principis ajuden a crear codi més mantenible, escalable i fàcil de comprendre. A continuació, s’introduiran breument cadascun d’ells:
S - Principi de Responsabilitat Única (Single Responsibility Principle)
Definició: Una classe hauria de tenir només una raó per canviar, cosa que significa que hauria de tenir només una tasca o responsabilitat.
Si us concentreu en aquest principi, el vostre codi serà més fàcil de testejar i mantenir perquè cada classe tindrà només una funció ben definida. Els beneficis són significatius:
- Facilitat de Manteniment: Les classes amb una única responsabilitat són més fàcils de comprendre i, per tant, més fàcils de modificar. No heu de preocupar-vos per com els canvis poden afectar altres comportaments encapsulats en la mateixa classe.
- Reutilització de Codis: Una classe amb una sola responsabilitat pot ser més fàcilment reutilitzada en altres parts de l’aplicació, o fins i tot en projectes futurs, ja que el seu comportament és més previsible i específic.
- Testeig més Senzill: És més fàcil escriure mocks i casos de prova per classes que tenen una sola responsabilitat. Els tests poden ser més enfocats i menys complexes, augmentant la confiança que esteu provant correctament el codi.
- Menys Errors: Quan una classe es canvia només per una raó, hi ha menys oportunitats de crear errors inadvertits. Això redueix el temps passat depurant i buscant problemes en funcions no relacionades.
- Organització millor del codis: Amb SRP, l’organització del codi tendeix a ser més clara. Cada classe té un propòsit ben definit, facilitant als desenvolupadors entendre com està estructurada l’aplicació.
- Facilitat per Escalar: Al tenir classes ben definides i separades per responsabilitat, és més fàcil escalar i expandir l’aplicació. Podreu afegir noves funcionalitats amb menys risc d’interferència amb codi existent.
- Integració i Desacoblament: SRP fomenta el baix acoblament, cosa que fa que les integracions siguin més fàcils de manegar. Les dependències són més clares i més fàcils de gestionar.
Seguir el Principi de Responabilitat Única pot semblar una sobrecàrrega al principi, però a llarg termini, desenvolupar amb aquest principi en ment establirà una base sòlida per a la comprensió de principis més avançats de disseny de programari.
O - Principi Obert/Tancat (Open/Closed Principle)
Definició: Les entitats de programari (classes, mòduls, funcions, etc.) haurien d’estar obertes per a l’extensió, però tancades per a la modificació.
Aplicant aquest principi, podreu afegir noves funcionalitats sense canviar el codi existent, reduint així la possibilitat d’introduir errors. El Principi Obert/Tancat (OCP) ofereix diversos beneficis clau:
- Extensibilitat: El principi facilita l’addició de noves funcionalitats sense modificar el codi existent. Això es tradueix en una millora de la productivitat i una reducció de la possibilitat d’introduir errors en el codi ja provat.
- Seguretat del Codi: Com que no necessiteu modificar el codi existent per expandir la funcionalitat, hi ha menys risc de trencar accidentalment el codi de producció, el que condueix a una base de codi més robusta.
- Promou el Disseny Modular: L’OCP anima a pensar en termes de mòduls independents i extensibles, el que pot resultar en un disseny de sistema més net i més fàcil d’entendre.
- Mantenibilitat: El codi que s’adhereix a l’OCP és generalment més fàcil de mantenir ja que les noves característiques solen ser implementades com a extensions en comptes de canvis.
- Reutilització del Codi: Les abstraccions i les extensions sovint poden ser reutilitzades en diferents parts de l’aplicació o en diferents projectes, maximitzant així la reutilització del codi.
- Facilita els Tests: Els mòduls que segueixen l’OCP solen ser més fàcils de mockejar i testejar en aïllament ja que l’impacte dels canvis es limita a les noves extensions.
- Reducció de costos a llarg termini: Encara que pot haver-hi una inversió inicial més gran en el disseny d’abstraccions i extensions, a llarg termini, el cost de manteniment i ampliació de l’aplicació es redueix significativament.
Per als desenvolupadors, aplicar el Principi Obert/Tancat pot significar una corba d’aprenentatge en el disseny de components desacoblats i en la definició d’interfícies. No obstant això, els beneficis a llarg termini en la qualitat del codi i la facilitat de manteniment fan que valgui la pena l’esforç inicial.
L - Principi de Substitució de Liskov (Liskov Substitution Principle)
Definició: Les classes derivades han de poder ser substituïbles per les seves classes base sense alterar el comportament correcte del programa.
Seguint aquest principi, assegurareu que les subclasses treballin i es comportin com s’espera en contextos on s’utilitza la classe base, afavorint la reutilització del codi. El Principi de Substitució de Liskov (LSP) és un element fonamental en el desenvolupament orientat a objectes i es veu potenciat quan s’aplica junt amb el disseny per contracte. Aquesta combinació porta a una sèrie de beneficis en la pràctica del desenvolupament de programari:
- Consistència i Fiabilitat: Els components poden ser intercanviats sense afectar la integritat del sistema, assegurant-se que les subclasses compleixin amb els “contractes” establerts per les seves classes base.
- Interoperabilitat: Els sistemes dissenyats seguint LSP són més propensos a ser interoperables, ja que els components poden ser substituïts o ampliats sense problemes de compatibilitat.
- Mantenibilitat i Extensibilitat Millorades: Amb els contractes clars, s’assegura que els nous components introduïts al sistema no violaran els requisits existents i augmentant la capacitat d’adaptar-se a canvis.
- Menor Risc d’Errors: L’aplicació de LSP amb disseny per contracte minimitza les sorpreses en temps d’execució causades per comportaments incorrectes de subclasses, resultats imprevistos o efectes secundaris no desitjats.
- Reutilització de Codis: La reutilització és més fàcil i segura, ja que els desenvolupadors poden confiar en que qualsevol subclasse que substitueix la classe base es comportarà d’acord amb el contracte establert.
- Documentació i Auto-documentació: Els contractes actuen com a documentació, explicitant les expectatives de cada classe i com aquestes interactuen entre elles, millorant la llegibilitat i comprensió del codi.
- Robustesa del Sistema: El sistema com a tot esdevé més robust quan cada peça compleix amb les promeses establertes, i es redueix la probabilitat d’un comportament imprevist en l’interacció entre components.
I - Principi de Segregació de la Interfície (Interface Segregation Principle)
Definició: Un client no hauria de ser forçat a dependre d’interfícies que no utilitza.
Aquest principi us incentiva a crear interfícies petites i específiques que són més fàcils d’implementar i mantenir, evitant dependències innecessàries. El Principi de Segregació de la Interfície (ISP) sosté que cap classe no hauria de ser forçada a dependre de mètodes que no fa servir. Els beneficis de seguir aquest principi són nombrosos i importants per al disseny de programari sòlid i sostenible:
- Codi Netejat i Focalitzat: En lloc d’una sola interfície immensa “fat interface”, l’ISP encoratja a descompondre en interfícies més petites i específiques, facilitant així que les classes implementin només les interfícies que necessiten.
- Prevenció de l’Acoblament Innecessari: Segregant les interfícies, es redueixen les dependències innecessàries, cosa que implica un risc menor de canvis en cascada a través del codi que pot ser difícil de mantenir i testejar.
- Major Facilitat de Mantenir: Si una interfície és canviada, només les classes que la implementen hauran de ser actualitzades, el que minimitza l’impacte dels canvis i els fa més manejables.
- Millor Organització i Comprehenent del Codis: Les interfícies especialitzades són més fàcils de comprendre i documentar, facilitant als desenvolupadors l’entendre el seu propòsit i com usar-les correctament.
- Desenvolupament Paral·lel i Agile: Diversos equips poden treballar simultàniament en diferents interfícies i implementacions sense trepitjar-se mútuament els peus. Això és particularment útil en mètodes de desenvolupament Agile, on diferents funcionalitats poden ser desenvolupades en paral·lel.
- Reusabilitat del Codi: Una interfície petita i ben definida és més probable que sigui reutilitzable, ja que l’acoblament feble significa que és més probable que serveixi a les necessitats d’una nova classe sense cap modificació.
- Substitució Simplificada: Si cal canviar una implementació per una altra, és més fàcil fer-ho si la interfície és petita i la nova implementació només ha de satisfer aquest conjunt reduït de mètodes.
D - Principi d’Inversió de Dependències (Dependency Inversion Principle)
Definició: Els mòduls d’alt nivell no haurien de dependre de mòduls de baix nivell. Ambdós haurien de dependre d’abstraccions. A més, les abstraccions no haurien de dependre de detalls. Els detalls haurien de dependre d’abstraccions.
Aquest principi us ajuda a reduir l’acoblament del codi i facilita el testeig i manteniment. El Principi d’Inversió de Dependències (DIP) es refereix a una forma específica de desacoblament de components de programari. Aquest principi té com a objectiu reduir la dependència en components de software concrets i, en canvi, fomentar una relació basada en abstraccions. Els beneficis de seguir el DIP són significatius:
- Acoblament Feble: El DIP redueix l’acoblament entre el codi de nivell alt i baix, fent que sigui més fàcil canviar una part del sistema sense afectar les altres.
- Facilitat de Testeig: El codi que depèn d’abstraccions és més fàcil de testejar. Es poden utilitzar mocks o stubs que implementin aquestes abstraccions durant les proves, sense la necessitat de comptar amb les implementacions reals.
- Reusabilitat Millorada: Les abstraccions no estan tan lligades als detalls d’implementació, cosa que fa que el codi sigui més reutilitzable en diferents contextos o projectes.
- Extensibilitat: És més fàcil ampliar el sistema amb nova funcionalitat o amb components alternatius, ja que les dependències són més genèriques i flexibles.
- Inversió de Control (IoC): El DIP és una part clau de IoC, que ajuda a desacoplar la lògica d’aplicació del framework o l’entorn d’execució, fent que el codi sigui més modular i mantenible.
- Mantenibilitat: Amb el DIP, es pot canviar la implementació d’una dependència concreta sense tocar el mòdul de nivell alt que la utilitza. Això significa que les actualitzacions, correccions de bugs, i millores poden ser més fàcils de manejar.
- Codi Orientat a l’Interfície: El DIP encoratja als desenvolupadors a pensar en interfícies i abstraccions des del començament, la qual cosa és una bona pràctica que porta a un disseny més net i més fàcil d’entendre.
- Major Estabilitat del Codis: Com que les classes d’alt nivell no depenen directament de classes de baix nivell, qualsevol canvi en la lògica de baix nivell és menys probable que provoqui errors en les classes d’alt nivell.
Recordem, els principis SOLID no són regles estrictes sinó més aviat directrius que poden ajudar-te a escriure millor codi.
Aquest article està pensat per ser una introducció bàsica als principis SOLID, proporcionant una comprensió fonamental i consells sobre com començar a aplicar-los.