Il Principio di Segregazione delle Interfacce (ISP) afferma che nessun client dovrebbe essere costretto a dipendere da metodi che non utilizza. Applicato correttamente, l’ISP riduce l’accoppiamento, semplifica i test e rende il codice più facile da modificare e comprendere. In molti progetti la maggior parte del lavoro di manutenzione deriva dall’adattamento di interfacce troppo ampie; dividere i contratti in responsabilità focalizzate riduce questo costo operativo.6
December 15, 2025 (4mo ago) — last updated April 28, 2026 (2d ago)
ISP: Guida pratica per sviluppatori TypeScript e React
Impara il Principio di Segregazione delle Interfacce (ISP) con esempi pratici in TypeScript e React per codice più modulare, testabile e manutenibile.
← Back to blog
ISP: Guida pratica per sviluppatori TypeScript e React
Sommario: Padroneggia il Principio di Segregazione delle Interfacce (ISP). Impara i concetti SOLID con esempi pratici in TypeScript e React per scrivere codice più pulito, testabile e manutenibile.
Introduzione
Il Principio di Segregazione delle Interfacce (ISP) afferma che nessun client dovrebbe essere costretto a dipendere da metodi che non utilizza. Applicato correttamente, l'ISP riduce l'accoppiamento, semplifica i test e rende il codice più facile da modificare e comprendere. In molti progetti la maggior parte del lavoro di manutenzione deriva dall’adattamento di interfacce troppo ampie; dividere i contratti in responsabilità focalizzate riduce questo costo operativo.6
Questa guida fornisce esempi pratici in TypeScript e React che puoi usare da subito per rendere il tuo codebase più modulare e manutenibile. Troverai pattern di refactor, checklist per le review e suggerimenti per automatizzare i controlli con strumenti come ESLint e assistenti di coding.
Cos’è il Principio di Segregazione delle Interfacce?
Immagina un telecomando con 90 pulsanti quando ti serve solo “Play.” Quella frustrazione rispecchia il software in cui una classe deve implementare un’interfaccia ampia e poco focalizzata. L’ISP, la “I” di SOLID, incoraggia la progettazione di interfacce piccole e specifiche per i client anziché un unico contratto che fa tutto. Questo evita l’anti-pattern della “interfaccia gonfia” o “God interface” e porta a sistemi più chiari e flessibili.1
Perché le interfacce gonfie fanno male
- Dipendenze non necessarie: le classi diventano accoppiate a metodi che non chiamano mai, rendendo rischiose modifiche non correlate.
- Sovraccarico cognitivo: gli sviluppatori devono scorrere metodi irrilevanti per trovare ciò che serve.
- Implementazioni vuote: le classi sono costrette a stubbare metodi non usati, aggiungendo boilerplate.
L’idea centrale è semplice: dare a ogni client esattamente ciò di cui ha bisogno, e nulla di più. Questo rende i componenti più facili da comprendere, testare ed evolvere.
Interfacce monolitiche vs. segregate
Un confronto rapido mette in chiaro i vantaggi dell’ISP.
| Attributo | Interfaccia monolitica (Anti-pattern) | Interfacce segregate (ISP) |
|---|---|---|
| Accoppiamento | Alto; le classi dipendono da metodi che non usano. | Basso; i client dipendono solo dai metodi necessari. |
| Coesione | Bassa; metodi non correlati raggruppati insieme. | Alta; ogni interfaccia serve un singolo ruolo. |
| Manutenibilità | Difficile; piccole modifiche si ripercuotono ampiamente. | Più facile; le modifiche riguardano solo i client rilevanti. |
| Testabilità | Difficile; i mock diventano grandi e fragili. | Più semplice; interfacce più piccole sono facili da mockare. |
Scegliere l’ISP aiuta il tuo codebase a rimanere adattabile quando aggiungi o rifattorizzi funzionalità.
ISP in pratica: violazioni comuni
Le violazioni non rompono l’app ma rendono la manutenzione dolorosa. Cerca classi piene di metodi vuoti o componenti con un gran numero di props opzionali.
Una classica “God Interface” in TypeScript (anti-pattern)
interface IUserActions {
createUser(data: UserData): void;
editUser(id: string, data: UserData): void;
deleteUser(id: string): void;
viewUserProfile(id: string): UserProfile;
changeUserRole(id: string, newRole: Role): void;
publishArticle(article: Article): void;
approveComment(commentId: string): void;
}
Una classe Viewer costretta a implementare questo includerà metodi privi di significato o che lanciano errori. Questo aumenta i costi di manutenzione e il rischio.
Props dei componenti gonfie in React
Un sintomo comune nel frontend è una Card generica con molte props opzionali. Questo crea ambiguità sulle combinazioni valide di props e costringe a rendering condizionali complessi.
interface CardProps {
title: string;
description?: string;
imageUrl?: string;
imageAltText?: string;
videoUrl?: string;
authorName?: string;
authorAvatarUrl?: string;
publicationDate?: string;
articleLink?: string;
onClick?: () => void;
// ... and many more optional props
}
Questi anti-pattern preparano il terreno per i passaggi di refactoring descritti di seguito.
Come rifattorizzare: da interfacce monolitiche a segregate
Rifattorizzare verso l’ISP non richiede una riscrittura massiccia. Usa piccoli cambi mirati per dividere responsabilità e chiarire i contratti.
1) Sistemare la “God Interface” in TypeScript
Step A: Identifica i ruoli dei client (per esempio: Admin, Editor, Viewer).
Step B: Crea interfacce specifiche per ruolo.
interface IViewerActions {
viewUserProfile(id: string): UserProfile;
}
interface IEditorActions {
publishArticle(article: Article): void;
approveComment(commentId: string): void;
}
interface IAdminActions {
createUser(data: UserData): void;
editUser(id: string, data: UserData): void;
deleteUser(id: string): void;
changeUserRole(id: string, newRole: Role): void;
}
Step C: Implementa solo ciò che serve.
class Viewer implements IViewerActions {
viewUserProfile(id: string): UserProfile {
console.log(`Fetching profile for user ${id}...`);
// ... fetch and return profile
}
}
Un Amministratore può implementare più interfacce secondo necessità. Questa separazione riduce ricompilazioni non necessarie e chiarisce chi possiede ogni capacità.
2) Rifattorizzare le props gonfie di React con union discriminate
Usa le union discriminate così che ogni variante di componente abbia un contratto chiaro. I tipi union e i discriminatori di TypeScript sono ideali per questo.2
type BaseCardProps = {
title: string;
onClick?: () => void;
};
type ImageCardProps = BaseCardProps & {
cardType: 'image';
imageUrl: string;
imageAltText: string;
};
type ArticleCardProps = BaseCardProps & {
cardType: 'article';
description: string;
authorName: string;
articleLink: string;
};
type CardProps = ImageCardProps | ArticleCardProps;
Con questo pattern l’editor impone immediatamente combinazioni valide di props e previene permutazioni non valide.
Audit e applicazione dell’ISP nel team
Fare correzioni una tantum è utile, ma incorporare l’ISP nelle pratiche di team dà valore duraturo. Combina criteri di audit chiari con controlli automatici per mantenere le interfacce sane.
Criteri di audit chiari
Crea una checklist condivisa per individuare violazioni ISP durante le review. Esempi di segnali d’allarme:
- Interfacce con molti metodi (ispeziona quando superano le cinque–sette funzioni).
- Metodi vuoti o stubbed nelle implementazioni.
- Nomi di interfacce vaghi che usano parole come “Manager” o “Handler.”
- Props dei componenti con molti campi opzionali.
Automazione dell’applicazione
ESLint e regole custom sono potenti per catturare pattern semplici, come props sovradimensionate o classi che implementano interfacce ma lasciano metodi non implementati.3 Assistenti di coding basati su AI possono aiutare a segnalare odori di design durante le review del codice e suggerire refactor mirati.4
Sia i controlli automatici che le review umane sono preziosi: gli strumenti forniscono coerenza e velocità, mentre le persone colgono il contesto e l’intento di business.
| Aspetto | Audit manuale | Applicazione automatica |
|---|---|---|
| Accuratezza | Alta per questioni contestuali | Coerente per regole definite |
| Coerenza | Varia a seconda del reviewer | Stesse regole applicate ovunque |
| Velocità | Lento per codebase grandi | Veloce, si integra con IDE/CI |
Usa entrambi: lascia che l’automazione gestisca i controlli di routine e che i reviewer si concentrino sulle decisioni di design più sfumate. Questa combinazione migliora i workflow TDD perché interfacce più piccole sono più semplici da mockare e testare, supportando cicli Red–Green–Refactor più rapidi.5
ISP e sviluppo assistito dall’AI
Interfacce chiare aiutano strumenti come i modelli stile GPT a ragionare sul codice: contratti piccoli e coerenti riducono l’ambiguità e migliorano la qualità dei suggerimenti automatici, dei refactor proposti e della documentazione generata.4
Interfacce pulite agiscono come un brief preciso per umani e macchine. Quella chiarezza riduce le supposizioni e produce cambiamenti assistiti dall’AI più accurati e affidabili.
Checklist rapida per il refactor
- Identificare ruoli e client per ogni interfaccia.
- Dividere grandi interfacce in contratti specifici per ruolo.
- Usare le union discriminate di TypeScript per le props variant dei componenti.2
- Aggiungere regole di lint per segnalare interfacce o props sovradimensionate.3
- Combinare controlli automatici con code review per decisioni più sfumate.
Domande frequenti (Q&A)
Q: Come riconosco rapidamente una violazione ISP?
A: Cerca interfacce con molti metodi non correlati, classi con implementazioni vuote o componenti con decine di props opzionali. Sono segnali che un contratto dovrebbe essere spezzato.
Q: Qual è il modo più rapido per correggere una “fat interface”?
A: Identifica i ruoli dei client, crea interfacce focalizzate per ruolo e aggiorna le implementazioni per implementare solo ciò che serve. Procedi in modo incrementale per ridurre il rischio.
Q: Come prevenire regressioni ISP in un codebase in crescita?
A: Aggiungi regole di lint e controlli in CI per rilevare interfacce sovradimensionate e includi una checklist di review per il design delle interfacce. Combina automazione con audit manuali periodici.
Tre Q&A concise
Q: L’ISP richiede interfacce monometodo?
A: No. Raggruppa i metodi che vengono sempre usati insieme dallo stesso client: l’obiettivo è coesione, non frammentazione eccessiva.
Q: ISP è la stessa cosa dello SRP?
A: No. SRP riguarda le classi (una sola ragione di cambiamento); ISP riguarda le interfacce (evitare metodi non usati dai client). È possibile rispettare SRP e violare ISP se una classe implementa un’interfaccia gonfia.
Q: Quando è accettabile ignorare l’ISP?
A: Principalmente per API o librerie di terze parti che non puoi cambiare, o quando tutti i client usano realmente tutti i metodi e l’interfaccia rimane coesa.
Presso Clean Code Guy aiutiamo i team ad applicare principi come l’ISP per costruire codebase manutenibili e pronti per l’AI. Ottieni un audit gratuito del codebase per trovare problemi nascosti e migliorare la manutenibilità a lungo termine.
L'AI scrive codice.Tu lo fai durare.
Nell'era dell'accelerazione AI, il codice pulito non è solo una buona pratica — è la differenza tra sistemi che si scalano e codebase che collassano sotto il loro stesso peso.