En tancar el mòdul 2 vas fer un diagnòstic incòmode del teu propi programa: retardMesGran, empleatRetardMesGran i llibreRetardMesGran són tres variables soltes que descriuen una sola cosa, i res no impedeix actualitzar-ne una i oblidar les altres dues. Aquest diagnòstic no és un detall d'estil: és el símptoma d'un límit estructural de l'estil de programació que has fet servir fins ara. Un programa procedimental organitza el codi en passos; quan els passos creixen, les dades relacionades es dispersen per variables independents i ningú no garanteix que continuïn essent coherents entre si. La programació orientada a objectes (POO) proposa una altra organització: agrupar les dades amb les operacions que les governen, en unitats anomenades objectes, de manera que una dada incoherent sigui impossible de construir. Aquesta lliçó encara no escriu la classe Llibre —això arriba a la següent—; la seva feina és que entenguis quin problema resol la POO, amb quin vocabulari es pensa i com es modela el domini de BiblioTech abans de teclejar una sola clau.
Contingut
- El punt de partida:
BiblioTechApp2.0 vista de prop - Per què el codi procedimental es degrada en créixer
- Què és l'orientació a objectes
- Classe enfront d'objecte: el plànol i la casa
- Identitat, estat i comportament
- Instància i referència
- Els quatre pilars d'un cop d'ull
- Modelar el domini: dels substantius a les classes
- El model objectiu de BiblioTech
- Relacions entre classes: associació, composició i agregació
- Avantatges reals de la POO... i els seus costos
- Errors Habituals i Consells
- Exercicis
- El punt de partida:
BiblioTechApp 2.0 vista de prop
BiblioTechApp 2.0 vista de propLa teva aplicació funciona. Mostra un menú, valida entrades, aplica les regles de negoci de Nexus Software i emet rebuts alineats. Però mira el bloc de declaracions amb què arrenca main:
// Regles de negoci
final int DIES_PRESTEC = 15;
final double TARIFA_DIARIA = 0.25;
final double MULTA_MAXIMA = 20.0;
final int LLINDAR_LLEU = 7;
// Dades de l'operacio en curs
String empleat;
String titol;
String isbn;
int diesTranscorreguts;
int diesRetard;
double multa;
String estat;
String gravetat;
// Estadistiques de sessio
int devolucions = 0;
int prestecs = 0;
double recaptacio = 0.0;
int retardMesGran = 0;
String empleatRetardMesGran = "-";
String llibreRetardMesGran = "-";Compta el que hi ha: vint variables en el mateix àmbit, totes visibles des de qualsevol punt de les dues-centes línies de main, totes modificables des de qualsevol punt, i cap relació explícita entre elles. El compilador no sap que titol i isbn descriuen el mateix llibre. No sap que retardMesGran i empleatRetardMesGran han de canviar alhora. No sap que multa mai no pot superar MULTA_MAXIMA. Tot això viu al teu cap i als comentaris.
- Per què el codi procedimental es degrada en créixer
L'estil procedimental —dades per una banda, passos per l'altra— funciona perfectament en programes petits. El problema apareix quan el programa creix, i es manifesta sempre de les mateixes quatre maneres:
| Símptoma | Com es veu a BiblioTech | Conseqüència |
|---|---|---|
| Dispersió de dades | titol, isbn, autor descriuen un llibre però són variables independents |
Res no garanteix que l'ISBN correspongui al títol |
| Estat global mutable | Les vint variables són visibles a tot main |
Qualsevol línia pot corrompre qualsevol dada |
| Regles duplicades | El sostre de multa s'aplica a la branca de devolució i a la taula d'escala | Si canvia la regla, cal buscar totes les còpies |
| Escalat impossible | Per a dos llibres caldrien titol1, isbn1, titol2, isbn2... |
El codi creix linealment amb les dades |
El quart símptoma és el més revelador. Pregunta't com registraries dues devolucions simultànies amb el disseny actual. La resposta honesta és: duplicant variables. I amb tres, triplicant-les. Aquest camí no porta enlloc.
flowchart LR
subgraph PROC["Procedimental"]
D1["titol"]
D2["isbn"]
D3["diesRetard"]
D4["multa"]
F1["calcular"]
F2["imprimir"]
F1 -.-> D1
F1 -.-> D3
F2 -.-> D2
F2 -.-> D4
end
subgraph OO["Orientat a objectes"]
O1["Llibre
titol, isbn
estaDisponible()"]
O2["Prestec
diesRetard, multa
calcularMulta()"]
O2 --> O1
end
A l'esquerra, dades i funcions es creuen en totes direccions. A la dreta, cada dada viu dins de la unitat que sap què fer-ne.
- Què és l'orientació a objectes
La POO és un paradigma: una manera d'organitzar un programa. La seva idea central cap en una frase:
Un programa és un conjunt d'objectes que col·laboren enviant-se missatges; cada objecte guarda les seves pròpies dades i és l'únic responsable de les operacions que les modifiquen.
Tres conseqüències immediates:
- Les dades deixen de ser passives. Un
Prestecno és una tupla de valors que algú inspecciona des de fora; és una entitat a qui preguntes quanta multa correspon. - Les regles viuen al costat de les dades que governen. La regla "la multa mai no supera 20 €" passa a ser un assumpte intern de
Prestec, no una línia perduda dins demain. - El programa es llegeix amb el vocabulari del negoci.
prestec.calcularMulta()s'entén sense conèixer la implementació;multa = diesRetard * TARIFA_DIARIA; if (multa >= MULTA_MAXIMA) multa = MULTA_MAXIMA;obliga a llegir aritmètica per deduir-ne la intenció.
Java és un llenguatge orientat a objectes per disseny: llevat dels vuit tipus primitius que vas veure al mòdul 1, tot el que has manipulat ja era un objecte. String, Scanner o System.out són objectes; scanner.nextLine() és exactament un missatge enviat a un objecte. Fa dos mòduls que fas servir POO sense saber-ho; el que comença ara és escriure els teus propis tipus.
- Classe enfront d'objecte: el plànol i la casa
Aquesta és la distinció fonamental, i convé fixar-la amb una analogia abans de veure sintaxi.
Una classe és un plànol d'arquitecte: descriu què tindrà cada casa (nombre d'habitacions, superfície) i què s'hi podrà fer (obrir la porta, encendre el llum). El plànol no és una casa: no hi pots viure, no té adreça postal i no es pot pintar de blau.
Un objecte és una casa construïda a partir d'aquest plànol: ocupa un lloc concret, té valors concrets (140 m², pintada de blau) i es pot fer servir. Del mateix plànol se'n construeixen mil cases, totes amb la mateixa estructura i cadascuna amb els seus propis valors.
| Concepte | Classe | Objecte |
|---|---|---|
| Naturalesa | Plantilla, definició, tipus | Exemplar concret en memòria |
| Quan existeix | En temps de compilació (és codi) | En temps d'execució (ocupa memòria) |
| Quants n'hi ha | Un per definició | Tants com se'n creïn |
| A BiblioTech | Llibre |
"Java Eficaç", "Refactorització" |
| Analogia | El plànol, el motlle, la recepta | La casa, la peça, el pastís |
Traduït al domini: escriuràs una classe Llibre i hi crearàs tres objectes, un per a "Java Eficaç" (ISBN 978-0000000001), un altre per a "Patrons de Disseny" (978-0000000002) i un altre per a "Refactorització" (978-0000000003). Els tres comparteixen estructura —tots tenen títol, autor, ISBN, any i disponibilitat— i difereixen en els valors.
- Identitat, estat i comportament
Tot objecte es descriu amb tres propietats. Interioritzar-les t'estalviarà confusions durant tot el mòdul.
- Identitat: quin objecte és, amb independència dels seus valors. Dos exemplars físics de "Java Eficaç" al prestatge són objectes diferents encara que comparteixin títol i ISBN. En Java la identitat és la posició en memòria, i és el que compara
==(ho vas veure al mòdul 1 amb el string pool, i tornarà a 03-09). - Estat: els valors que l'objecte guarda en un instant. L'estat d'un
Llibreincloutitol,autor,isbn,anyPublicacioidisponible. L'estat canvia:disponiblepassa detrueafalsequan algú se l'emporta. - Comportament: les operacions que l'objecte sap fer. Un
Prestecsap calcular els seus dies de retard, la seva multa i la seva gravetat.
Aplicat al vocabulari que ja utilitzes:
| Classe | Estat (atributs) | Comportament (operacions) |
|---|---|---|
Llibre |
titol, autor, isbn, anyPublicacio, disponible |
prestar-se, retornar-se, dir si està disponible |
Empleat |
nom, identificador, préstecs acumulats |
registrar un préstec, dir quants n'acumula |
Prestec |
llibre, empleat, diesTranscorreguts |
calcular diesRetard, multa, gravetat, estat |
Fixa't en un detall que governarà tot el mòdul: la columna de la dreta és el que avui està solt dins de main. La POO no inventa comportament nou; el muda de lloc, del procediment a l'objecte que li correspon.
- Instància i referència
Dues paraules que sentiràs constantment i que convé separar des d'ara:
- Instància és sinònim d'objecte: l'exemplar concret creat a partir d'una classe. "Crear una instància de
Llibre" i "crear un objecteLlibre" volen dir el mateix. - Referència és la variable amb què arribes a aquest objecte. No és l'objecte: és l'adreça on viu.
La distinció importa perquè en Java mai no manipules objectes directament, sempre a través de referències. Quan escrius:
passen tres coses independents: es reserva memòria per a un objecte Llibre al heap (al mòdul 1 en dèiem "monticle"), es declara una variable javaEficac a la pila, i es guarda en aquesta variable l'adreça de l'objecte. Una conseqüència immediata, que la lliçó 03-02 desenvolupa amb detall: dues referències poden apuntar al mateix objecte, i llavors un canvi fet a través d'una es veu a través de l'altra.
- Els quatre pilars d'un cop d'ull
La POO se sosté sobre quatre idees. Aquí les tens en una frase cadascuna, amb la lliçó on es desenvolupen; no intentis dominar-les ara, només reconèixer-ne els noms quan apareguin.
| Pilar | En una frase | Exemple a BiblioTech | Lliçó |
|---|---|---|---|
| Encapsulament | L'objecte amaga la seva representació interna i només exposa operacions controlades | Ningú no pot assignar una multa arbitrària: es calcula en retornar | 03-07 |
| Herència | Una classe es pot definir com una especialització d'una altra i reutilitzar el que aquesta ja defineix | Llibre, Revista i Dvd són tipus de Material prestable |
03-05 |
| Polimorfisme | Una mateixa crida produeix comportaments diferents segons el tipus real de l'objecte | material.calcularMulta() cobra 0,25 €/dia si és llibre i 0,50 €/dia si és DVD |
03-06 |
| Abstracció | Es modela només l'essencial per al problema i s'amaga la resta | A BiblioTech li importa l'ISBN d'un llibre, no el seu pes ni el color de la portada | 03-08 |
Un apunt d'honestedat: aquests quatre termes es reciten molt i s'entenen poc. Al final del mòdul no els hauràs memoritzat, els hauràs fet servir, que és l'única manera d'aprendre'ls.
- Modelar el domini: dels substantius a les classes
Abans d'escriure codi cal decidir quines classes existeixen. Hi ha una tècnica senzilla i sorprenentment eficaç per començar: subratllar els substantius de l'enunciat del problema. Aquest és l'enunciat de BiblioTech tal com el donaria el departament de Nexus Software:
La biblioteca tècnica interna gestiona els llibres que els empleats prenen en préstec. Cada llibre té títol, autor, ISBN i any de publicació, i pot estar disponible o no. Un préstec dura 15 dies; passat aquest termini s'acumulen dies de retard que generen una multa de 0,25 € diaris amb un màxim de 20 €. Un retard de fins a 7 dies es considera lleu; per damunt, greu.
Substantius candidats: biblioteca, llibre, empleat, préstec, títol, autor, ISBN, any, dies, multa, retard.
Ara es filtren amb tres criteris:
- Té identitat pròpia i estat que canvia? → és candidat a classe. Llibre, Empleat, Préstec ho compleixen.
- És un simple valor descriptiu d'una altra cosa? → és candidat a atribut. Títol, ISBN, any descriuen un llibre; dies de retard i multa descriuen un préstec.
- És el sistema sencer o un concepte vague? → normalment no és una classe de domini. Biblioteca és el sistema; el que apareixerà més endavant és un
Catalegque guarda materials i unGestorPrestecsque orquestra operacions (mòduls 5 i següents).
Resultat del filtratge per a aquest mòdul: tres classes, Llibre, Empleat i Prestec, exactament les que es van anunciar en tancar el mòdul 2.
I una pregunta que separa un model bo d'un de mediocre: de qui és cada responsabilitat? Una responsabilitat mal col·locada compila igual, però enverina el disseny.
| Responsabilitat | De qui? | Per què |
|---|---|---|
| Saber el seu ISBN | Llibre |
És una dada intrínseca del llibre |
| Saber si està prestat | Llibre |
És un estat de l'exemplar |
| Calcular els dies de retard | Prestec |
Depèn del termini i del temps transcorregut, no del llibre |
| Calcular la multa | Prestec |
És una conseqüència del retard d'aquella operació |
| Saber quants préstecs acumula | Empleat |
És historial de la persona |
| Imprimir el rebut | Ni Llibre ni Prestec |
És presentació; se separa del domini (lliçó 03-08) |
- El model objectiu de BiblioTech
Aquest és el model al qual arribaràs en acabar el mòdul. Guarda'l com a mapa: cada lliçó hi afegeix una peça.
classDiagram
class Llibre {
-String titol
-String autor
-String isbn
-int anyPublicacio
-boolean disponible
+estaDisponible() boolean
+prestar() void
+retornar() void
+toString() String
+equals(Object) boolean
}
class Empleat {
-String nom
-String identificador
-int prestecsAcumulats
+registrarPrestec() void
+getPrestecsAcumulats() int
+toString() String
}
class Prestec {
-Llibre llibre
-Empleat empleat
-int diaPrestec
-int diaVenciment
-int diesTranscorreguts
+calcularDiesRetard() int
+calcularMulta() double
+classificarGravetat() String
+registrarDevolucio(int) void
+toString() String
}
Prestec --> Llibre : llibre prestat
Prestec --> Empleat : sollicitant
Llegeix-lo així: un Prestec coneix un Llibre i un Empleat; ni el llibre ni l'empleat no necessiten conèixer el préstec. Les fletxes indiquen la direcció de la dependència, i aquesta direcció és una decisió de disseny, no un accident.
A la lliçó 03-05 aquest diagrama creixerà cap amunt: apareixerà una classe Material de la qual Llibre, Revista i Dvd seran especialitzacions.
- Relacions entre classes: associació, composició i agregació
Les classes rarament viuen aïllades. Hi ha tres formes típiques de relacionar-se, a més de l'herència:
| Relació | Significat | Durada del vincle | Exemple a BiblioTech |
|---|---|---|---|
| Associació | "usa" o "coneix" | Independent | Prestec coneix l'Empleat que el sol·licita |
| Agregació | "té un" amb parts que sobreviuen al tot | El tot pot desaparèixer i les parts continuen | Un Cataleg agrega Llibres: si s'esborra el catàleg, els llibres existeixen igual |
| Composició | "està format per" amb parts que moren amb el tot | Les parts no tenen sentit sense el tot | Un Prestec composa el seu propi registre de dates i estat |
| Herència | "és un" | Estructural, en temps de compilació | Un Llibre és un Material (lliçó 03-05) |
La prova pràctica per distingir agregació de composició és preguntar-se: si destrueixo l'objecte contenidor, té sentit que la part continuï existint? Si la resposta és sí, és agregació; si és no, composició. Un llibre sobreviu al catàleg que el llista; el desglossament intern d'una multa no sobreviu al préstec que la va generar.
No t'obsessionis amb aquestes etiquetes: en codi Java, associació, agregació i composició s'escriuen gairebé igual (un camp que referencia un altre objecte). El seu valor és en el disseny i en la conversa amb altres desenvolupadors.
- Avantatges reals de la POO... i els seus costos
Els cursos solen enumerar només la columna esquerra. Un professional necessita les dues.
| Avantatges | Costos |
|---|---|
| Les dades relacionades viatgen juntes i no es descoordinen | Indirecció: per saber què fa prestec.calcularMulta() cal obrir un altre fitxer |
| Les regles de negoci són en un únic lloc | Cerimònia: més fitxers, més línies per al mateix en programes petits |
| El codi es llegeix amb el vocabulari del negoci | Sobredisseny: és fàcil crear jerarquies de set nivells per a un problema de dos |
| Afegir un tipus nou no obliga a tocar el codi existent (03-06) | Corba d'aprenentatge: herència i polimorfisme tenen paranys subtils |
| Cada classe es pot provar per separat (mòdul 11) | Acoblament ocult: una classe base mal dissenyada trenca totes les seves filles (03-05) |
Regla pràctica que et servirà durant anys: la POO paga quan el programa ha de créixer i canviar. Un script de trenta línies que s'executa un cop no necessita classes. BiblioTech sí: creixerà durant deu mòduls més.
Errors Habituals i Consells
- Confondre classe amb objecte en parlar-ne. "Modificaré el llibre" és ambigu: la classe
Llibre(el plànol, i afecta tothom) o l'objectejavaEficac(un exemplar)? Acostuma't a anomenar la classe en majúscula i singular (Llibre) i els objectes amb noms concrets (javaEficac). - Convertir en classe tot substantiu de l'enunciat. No tot allò que es pot anomenar mereix una classe.
titolés unString, no una classeTitol. Aplica el filtre de l'apartat 8: identitat + estat que canvia. - Crear classes que només guarden dades. Una classe amb cinc camps i deu getters, sense cap comportament, és una estructura de dades disfressada (se'n diu model anèmic). Pregunta't sempre què sap fer la classe, no només què conté.
- Col·locar el comportament a la classe equivocada. Si
Llibrecalculés multes, hauria de conèixer terminis, tarifes i dies transcorreguts, dades que no li pertanyen. Cada operació va on són les dades que necessita. - Començar per l'herència. És el pilar més cridaner i el més perillós. Modela primer classes planes que funcionin; la jerarquia apareixerà sola quan la necessitis (lliçó 03-05).
- Consell: dibuixa abans de teclejar. Cinc minuts de diagrama de classes en paper estalvien hores de refactorització. No necessites UML formal: caixes amb nom, atributs i fletxes ja n'hi ha prou.
- Consell: anomena en l'idioma del negoci.
Prestec,LlibreiEmpleatsón millors noms queDataRecord,ItemoManager, perquè qualsevol persona de Nexus Software els entén sense explicació.
Exercicis
Exercici 1: identificar classes, atributs i responsabilitats
Nexus Software vol ampliar BiblioTech amb un mòdul de sales de reunions:
Els empleats reserven sales de reunions. Cada sala té un nom, una capacitat màxima de persones i un equipament (projector sí o no). Una reserva la fa un empleat per a una sala, en una franja horària concreta, amb un nombre d'assistents que no pot superar la capacitat de la sala. Una reserva es pot cancel·lar.
Sense escriure codi Java complet:
- Enumera els substantius i classifica'ls en classe, atribut o descartat, justificant cada decisió.
- Escriu una taula de responsabilitats: què ha de saber fer cada classe.
- Indica quin tipus de relació (associació, agregació o composició) hi ha entre
ReservaiSala, i entreReservaiEmpleat.
Exercici 2: diagrama i esquelets de classe
Amb el resultat de l'exercici 1:
- Dibuixa el diagrama
classDiagramde mermaid del model de sales. - Escriu els esquelets de les classes (només la declaració i els camps, amb comentaris on anirien les operacions). No implementis res: la sintaxi completa arriba a 03-02.
Exercici 3: detectar responsabilitats mal col·locades
Un company proposa aquest disseny per a BiblioTech. Assenyala tres decisions que consideris errònies i explica on hauria de viure cada responsabilitat:
class Llibre {
String titol;
String isbn;
double multaDelDarrerPrestec; // (a)
String nomDeLempleatActual; // (b)
void imprimirRebutDeDevolucio() { } // (c)
void guardarEnFitxer() { } // (d)
}Solucions
Solució 1
1. Classificació de substantius
| Substantiu | Classificació | Justificació |
|---|---|---|
| Empleat | Classe | Ja existeix al model; té identitat i estat propi |
| Sala | Classe | Té identitat (cada sala és diferent) i estat (equipament, capacitat) |
| Reserva | Classe | Té identitat, estat que canvia (activa/cancel·lada) i comportament (cancel·lar-se) |
| Nom, capacitat, projector | Atributs de Sala |
Són valors que descriuen la sala, no entitats amb vida pròpia |
| Franja horària, assistents | Atributs de Reserva |
Descriuen una reserva concreta |
| Mòdul, sistema | Descartats | Són el programa sencer, no conceptes del domini |
Un matís professional: franja horària podria arribar a ser una classe pròpia (Franja, amb hora d'inici i de fi, i capaç de dir si se solapa amb una altra). És una decisió legítima, però prematura ara: comença per atributs i promou a classe només quan el concepte acumuli comportament propi.
2. Responsabilitats
| Classe | Ha de saber |
|---|---|
Sala |
El seu nom, la seva capacitat i si té projector; dir si admet un nombre d'assistents |
Empleat |
El seu nom i identificador; quantes reserves acumula |
Reserva |
Quina sala, quin empleat, quina franja i quants assistents; validar que hi caben; cancel·lar-se; dir si està activa |
Observa que "dir si admet N assistents" és de Sala, perquè la capacitat és una dada seva; en canvi "validar que hi caben" és de Reserva, perquè només la reserva coneix el nombre d'assistents. Cadascuna aporta el que sap.
3. Relacions
Reserva→Sala: associació (o agregació). La sala existeix abans i després de la reserva; cancel·lar una reserva no destrueix la sala.Reserva→Empleat: associació. L'empleat té vida pròpia a l'empresa.
No hi ha composició evident en aquest model, llevat que la franja horària es modelés com a objecte intern de la reserva: llavors sí que seria composició, perquè aquesta franja no significa res fora de la seva reserva.
Solució 2
Diagrama
classDiagram
class Sala {
-String nom
-int capacitatMaxima
-boolean teProjector
+admet(int assistents) boolean
}
class Empleat {
-String nom
-String identificador
-int reservesAcumulades
}
class Reserva {
-Sala sala
-Empleat sollicitant
-int horaInici
-int horaFi
-int assistents
-boolean activa
+cancellar() void
+estaActiva() boolean
}
Reserva --> Sala : reserva
Reserva --> Empleat : sollicitada per
Esquelets
package com.nexussoftware.bibliotech.domini;
public class Sala {
String nom;
int capacitatMaxima;
boolean teProjector;
// Operacions previstes:
// admet(int assistents) -> boolean
}package com.nexussoftware.bibliotech.domini;
public class Reserva {
Sala sala; // referencia a un altre objecte: associacio
Empleat sollicitant; // associacio
int horaInici; // 9 = 09:00, format enter provisional
int horaFi;
int assistents;
boolean activa;
// Operacions previstes:
// cancellar() -> void
// estaActiva() -> boolean
// hiCabenTots() -> boolean (delega en sala.admet(assistents))
}Dos detalls que reapareixeran: els camps que referencien altres classes (Sala sala) són exactament el que dibuixàvem com a fletxa al diagrama, i les hores es modelen com a enters perquè LocalTime pertany a java.time, que s'estudia a la lliçó 10-05.
Solució 3
(a) multaDelDarrerPrestec a Llibre està mal col·locat. La multa és conseqüència d'una operació de préstec concreta, no una propietat del llibre. Amb aquest disseny, si el mateix exemplar es presta cinc vegades, el camp només recorda la darrera multa i perd l'historial; i pitjor encara, obliga Llibre a conèixer terminis i tarifes, que no són assumpte seu. La multa pertany a Prestec.
(b) nomDeLempleatActual a Llibre està malament per dues raons. Primera, és la mateixa dispersió que pateix avui BiblioTechApp: guardar el nom en lloc de l'Empleat deixa la dada òrfena i sense possibilitat d'accedir a l'identificador ni als préstecs acumulats. Segona, i més important, el vincle llibre–empleat només existeix mentre hi ha un préstec, així que el seu lloc natural és la classe Prestec, que ja relaciona tots dos. Si Llibre ha de saber alguna cosa, és únicament si està disponible o no.
(c) imprimirRebutDeDevolucio() barreja domini i presentació. Una classe de domini no hauria de saber que existeix una consola, ni el format del rebut, ni l'amplada de les columnes. Si demà BiblioTech es converteix en aplicació web (mòdul 12), caldria reescriure la classe sencera. El rebut el genera qui s'ocupa de la interfície. És el problema dels nivells d'abstracció barrejats, que es tracta a fons a la lliçó 03-08.
(d) guardarEnFitxer() afegeix una responsabilitat aliena. Persistir en disc és un assumpte d'infraestructura (mòdul 7), no del concepte "llibre". Una classe amb dos motius diferents per canviar —canvia el negoci, canvia el format de fitxer— és una classe que farà infeliç qui la mantingui.
Disseny corregit, en esquelet:
public class Llibre {
String titol;
String autor;
String isbn;
int anyPublicacio;
boolean disponible;
// Operacions: estaDisponible(), prestar(), retornar()
}
public class Prestec {
Llibre llibre; // que es presta
Empleat empleat; // a qui es presta
int diesTranscorreguts;
// Operacions: calcularDiesRetard(), calcularMulta(), classificarGravetat()
}Conclusió
En aquesta lliçó has canviat de manera de pensar abans de canviar de manera d'escriure. Has vist per què l'estil procedimental es degrada quan el programa creix —dades disperses, estat global, regles duplicades, impossibilitat d'escalar—, amb el teu propi BiblioTechApp com a cas d'estudi. Has après el vocabulari essencial: classe com a plànol i objecte com a exemplar, identitat, estat i comportament, instància i referència. Tens un mapa dels quatre pilars i de la lliçó on es desenvolupa cadascun. I, sobretot, has modelat el domini de BiblioTech: dels substantius de l'enunciat a tres classes —Llibre, Empleat, Prestec— amb responsabilitats explícites, relacions dibuixades i un diagrama objectiu que guiarà la resta del mòdul. També saps que la POO no és gratis: costa indirecció, cerimònia i risc de sobredisseny, i només es paga sola quan el programari ha de créixer.
Tens el plànol. A la lliçó següent, Classes i objectes, comences a construir: declararàs la classe Llibre amb la seva sintaxi exacta, veuràs quin valor prenen els camps abans d'assignar-los res, crearàs objectes amb new seguint pas a pas què passa a la pila i al heap, descobriràs què significa de debò un NullPointerException i per què dues referències al mateix objecte poden provocar sorpreses desagradables. En acabar-la, "Java Eficaç", "Patrons de Disseny" i "Refactorització" hauran deixat de ser cadenes de text soltes per convertir-se en tres objectes amb vida pròpia dins de BiblioTechApp.
Curs de Programació en Java
Mòdul 1: Introducció a Java
- Introducció a Java
- Configuració de l'entorn de desenvolupament
- Sintaxi i estructura bàsica
- Variables i tipus de dades
- Operadors
- Entrada i sortida per consola
- El teu primer programa complet: BiblioTech
Mòdul 2: Flux de control
- Sentències condicionals
- Bucles
- Sentències switch
- Break i continue
- Depuració i traces d'execució
- Projecte: menú interactiu de BiblioTech
Mòdul 3: Programació orientada a objectes
- Introducció a la POO
- Classes i objectes
- Mètodes
- Constructors
- Herència
- Polimorfisme
- Encapsulament
- Abstracció
- La classe Object: equals, hashCode i toString
Mòdul 4: Programació orientada a objectes avançada
- Interfícies
- Classes abstractes
- Classes internes
- Classes anònimes
- Expressions lambda
- Interfícies funcionals i referències a mètodes
- Enumeracions i registres
Mòdul 5: Estructures de dades i col·leccions
- Arrays
- El framework de col·leccions
- ArrayList
- LinkedList
- HashMap
- HashSet
- Cua i Deque
- Pila
- Ordenació i cerca en col·leccions
Mòdul 6: Gestió d'excepcions
- Introducció a les excepcions
- Bloc try-catch
- Throw i throws
- Excepcions personalitzades
- Bloc finally
- Try-with-resources i AutoCloseable
- Estratègies de gestió d'errors i logging
Mòdul 7: Entrada/sortida de fitxers
- Lectura de fitxers
- Escriptura de fitxers
- Fluxos de fitxers
- BufferedReader i BufferedWriter
- Serialització
- L'API NIO.2: Path i Files
- Formats d'intercanvi: CSV i Properties
Mòdul 8: Multifil i concurrència
- Introducció al multifil
- Creació de fils
- Cicle de vida d'un fil
- Sincronització
- Utilitats de concurrència
- Col·leccions concurrents i variables atòmiques
- Tasques asíncrones amb CompletableFuture
Mòdul 9: Xarxes
- Introducció a les xarxes
- Sockets
- ServerSocket
- DatagramSocket i DatagramPacket
- URL i HttpURLConnection
- El client HTTP modern
Mòdul 10: Temes avançats
- Genèrics
- Anotacions
- Reflexió
- Característiques de Java 8: Streams i Optional
- Dates i hores amb java.time
- Java 9 i més enllà
- Memòria, recol·lecció de brossa i rendiment
Mòdul 11: Frameworks i llibreries de Java
- Introducció als frameworks de Java
- Spring Framework
- Hibernate
- JUnit
- Maven
- Proves avançades amb Mockito
- Llibreries essencials de l'ecosistema
