modulo 14 di 24 / Ore 21-40
Moduli 9-16 / Checkpoint 40 ore
Estrarre funzioni piccole da funzioni lunghe
Come identificare funzioni lunghe nel Registro e estrarle in funzioni più piccole con nomi precisi — con esempio concreto before/after su un event listener o caso d'uso.
Estrarre funzioni piccole da funzioni lunghe
Questa lezione appartiene al Modulo 14 — Refactoring.
Il lavoro continua il progetto guida, il Registro del laboratorio scolastico. In questa lezione impari a riconoscere le funzioni troppo lunghe nel Registro e a estrarle in funzioni più piccole con nomi precisi.
Obiettivo della lezione
Identificare almeno una funzione lunga nel tuo Registro (più di 20 righe) e scomporla in funzioni più piccole con nomi che descrivono esattamente cosa fanno. Il comportamento deve restare identico.
Alla fine devi avere: la funzione originale lunga sostituita da chiamate a funzioni estratte, con nomi chiari e responsabilità singola.
Come riconoscere una funzione da estrarre
Una funzione è candidata all’estrazione quando:
- ha più di 15-20 righe
- fa più di una cosa (lo puoi vedere dai commenti interni)
- ha blocchi di codice separati da righe vuote che svolgono compiti distinti
- contiene logica che potresti voler riusare in un altro punto
Il segnale più chiaro: se devi aggiungere un commento dentro la funzione per spiegare cosa fa una parte di codice, quella parte è un buon candidato per l’estrazione.
Nel Registro del laboratorio
Le funzioni più spesso troppo lunghe nel Registro sono:
- i gestori degli eventi nella Presentation (leggono input + validano + chiamano caso d’uso + aggiornano UI)
- i casi d’uso che coordinano più operazioni senza separazione chiara
- l’adapter localStorage quando gestisce mapping e validazione nella stessa funzione
Procedura guidata
- Apri ogni file del Registro e conta le righe di ogni funzione.
- Identifica le funzioni con più di 15 righe.
- Per ogni funzione, identifica i “blocchi” di logica (separati da righe vuote o commenti).
- Estrai ogni blocco in una funzione con un nome preciso.
- Sostituisci il blocco originale con la chiamata alla funzione estratta.
- Verifica che il comportamento sia invariato.
- Commita.
Attività in classe
Compila questa scheda prima di iniziare:
## Analisi funzioni lunghe
File: ___
Funzione più lunga: ___ (N righe)
Blocchi identificati:
1. (descrizione)
2. (descrizione)
3. (descrizione)
Nomi proposti per le funzioni da estrarre:
1. ___
2. ___
3. ___
Spiegazione guidata per studiare
L’estrazione di funzioni è il refactoring più semplice e più utile. Il principio è: ogni funzione fa una sola cosa, e il suo nome descrive cosa fa. Se il nome della funzione usa “e” o “oppure”, probabilmente fa più di una cosa.
Un errore comune è estrarre funzioni private che non dicono nulla: _passo1, _helper, _aux. Il nome deve essere preciso: validaInputPrestito, aggiornaStratoStrumento, costruisciMessaggioSuccesso. Se non riesci a trovare un nome preciso, probabilmente il blocco non ha ancora una responsabilità chiara.
Passo per passo nel progetto
Esempio concreto: un gestore di eventi nella Presentation troppo lungo.
Versione originale con tutto nella stessa funzione:
// presentation/azioni.js — PRIMA
btnPresta.addEventListener("click", () => {
// parte 1: leggi e valida input
const strumentoId = inputId.value.trim();
if (!strumentoId) {
messaggioUscita.textContent = "Inserisci un ID strumento valido.";
return;
}
// parte 2: chiama il caso d'uso
let prestito;
try {
prestito = apriPrestito({ strumentoId }, archivioStrumenti, archivioPrestiti);
} catch (errore) {
const messaggi = {
"STRUMENTO_NON_TROVATO": "Strumento non trovato.",
"STRUMENTO_NON_DISPONIBILE": "Lo strumento non è disponibile.",
"ARCHIVIO_NON_DISPONIBILE": "Errore nel salvataggio."
};
messaggioUscita.textContent = messaggi[errore.message] ?? "Operazione non riuscita.";
return;
}
// parte 3: aggiorna la UI
messaggioUscita.textContent = `Prestito aperto. ID: ${prestito.id}`;
inputId.value = "";
aggiornaListaStrumenti(archivioStrumenti);
});
Questa funzione fa tre cose: legge/valida input, chiama il caso d’uso, aggiorna la UI. Estrazione:
// presentation/azioni.js — DOPO
function leggiInputStrumentoId() {
return inputId.value.trim();
}
function mostraErrore(messaggioErrore) {
const messaggi = {
"STRUMENTO_NON_TROVATO": "Strumento non trovato.",
"STRUMENTO_NON_DISPONIBILE": "Lo strumento non è disponibile.",
"ARCHIVIO_NON_DISPONIBILE": "Errore nel salvataggio."
};
messaggioUscita.textContent = messaggi[messaggioErrore] ?? "Operazione non riuscita.";
}
function mostraSuccessoPrestito(prestito) {
messaggioUscita.textContent = `Prestito aperto. ID: ${prestito.id}`;
inputId.value = "";
aggiornaListaStrumenti(archivioStrumenti);
}
btnPresta.addEventListener("click", () => {
const strumentoId = leggiInputStrumentoId();
if (!strumentoId) {
mostraErrore("INPUT_VUOTO"); // può essere gestito in mostraErrore
return;
}
try {
const prestito = apriPrestito({ strumentoId }, archivioStrumenti, archivioPrestiti);
mostraSuccessoPrestito(prestito);
} catch (errore) {
mostraErrore(errore.message);
}
});
Il gestore del click ora ha 10 righe invece di 25. Ogni funzione estratta ha un nome preciso e una responsabilità sola.
Secondo esempio: estrazione dall’adapter localStorage.
// infrastructure/archivioStrumentiLocalStorage.js — PRIMA
export function caricaTutti() {
const raw = localStorage.getItem("registro_strumenti");
if (!raw) return [];
try {
const dati = JSON.parse(raw);
if (!Array.isArray(dati)) return [];
return dati.map(dto => ({
id: dto.id,
nome: dto.name,
categoria: dto.category,
stato: dto.status
}));
} catch {
return [];
}
}
// DOPO — funzioni estratte con nomi precisi
function leggiDaLocalStorage(chiave) {
try {
const raw = localStorage.getItem(chiave);
if (!raw) return null;
return JSON.parse(raw);
} catch {
return null;
}
}
function dtoToStrumento(dto) {
return {
id: dto.id,
nome: dto.name,
categoria: dto.category,
stato: dto.status
};
}
export function caricaTutti() {
const dati = leggiDaLocalStorage("registro_strumenti");
if (!Array.isArray(dati)) return [];
return dati.map(dtoToStrumento);
}
Prova di comprensione
Rispondi per iscritto:
- Quale funzione nel tuo Registro era la più lunga? Quante righe aveva?
- Quali blocchi hai identificato dentro quella funzione?
- Come hai scelto i nomi delle funzioni estratte?
- Dopo l’estrazione, la funzione originale è diventata più facile da leggere? Perché?
Errori da evitare
- estrarre funzioni con nomi generici come
_helpero_utils; - estrarre blocchi di codice che non hanno una responsabilità chiara — prima chiariscila, poi estrai;
- estrarre funzioni che vengono usate solo una volta senza un buon motivo (aggiunge complessità senza beneficio);
- dimenticare di verificare il comportamento dopo l’estrazione.
Prodotto da consegnare
Almeno una funzione lunga del Registro scomposta in funzioni più piccole con nomi precisi. Come verifica: mostra il before e l’after del codice e spiega verbalmente il nome e il ruolo di ogni funzione estratta.
Checklist di chiusura
- ho identificato almeno una funzione con più di 15 righe;
- i blocchi di codice sono stati estratti in funzioni con nomi precisi;
- ogni funzione estratta fa una sola cosa;
- il comportamento è identico prima e dopo l’estrazione;
- ho committato le modifiche con un messaggio
refactor: estrae funzioni da [nome funzione].
Risultato atteso
Ho estratto funzioni da: [nome funzione originale] in [file].
Prima aveva N righe. Dopo la funzione principale ha M righe.
Funzioni estratte: [lista con nomi].
Ogni funzione estratta fa una sola cosa: [descrizione per ognuna].
I test passano. Commit: "refactor: estrae funzioni da gestore click btnPresta".