December 15, 2025 (4mo ago)

Guida per sviluppatori al Principio di Segregazione delle Interfacce

Padroneggia il Principio di Segregazione delle Interfacce (ISP). Impara i concetti SOLID con esempi pratici in TypeScript e React per scrivere codice più pulito e manutenibile.

← Back to blog
Cover Image for Guida per sviluppatori al Principio di Segregazione delle Interfacce

Padroneggia il Principio di Segregazione delle Interfacce (ISP). Impara i concetti SOLID con esempi pratici in TypeScript e React per scrivere codice più pulito e manutenibile.

Principio di Segregazione delle Interfacce (ISP) - TypeScript & 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 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. Questa guida mostra esempi pratici in TypeScript e React che puoi usare oggi per rendere il tuo codebase più modulare e manutenibile.


Cos'è il Principio di Segregazione delle Interfacce?

A diagram comparing a multi-tool as a bloated interface to a single screwdriver as a focused interface.

Immagina un telecomando con 90 pulsanti quando ti serve solo "Play." Quella frustrazione rispecchia il software in cui una classe deve implementare un'interfaccia grande 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 fianco a fianco rende chiari i compromessi.

AttributoInterfaccia monolitica (Anti-pattern)Interfacce segregate (ISP)
AccoppiamentoAlto; le classi dipendono da metodi che non usano.Basso; i client dipendono solo dai metodi necessari.
CoesioneBassa; 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 all'aggiunta o rifattorizzazione delle 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.

A conceptual 'God Interface' diagram shows admin and viewer roles interacting with various icons.

Una classica "God Interface" in TypeScript

// ANTI-PATTERN: A "fat interface" that violates ISP 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.

// ANTI-PATTERN: A bloated props interface 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 ci preparano ai 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.

Hand-drawn diagram showing refactoring of 'I user Actions' into 'Editor' and 'Viewer' specific interfaces.

1) Sistemare la "God Interface" in TypeScript

Step A: Identificare i ruoli dei client. Per esempio: Admin, Editor, Viewer.

Step B: Creare interfacce specifiche per ruolo.

// GOOD: Focused interfaces 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: Implementare 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 le 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

// GOOD: Base props type BaseCardProps = { title: string; onClick?: () => void; };

// GOOD: Specific variants 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 (vale la pena ispezionare 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.

Un approccio comune è affiancare la review manuale con strumenti automatici per scalare l'applicazione delle regole.

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 anche aiutare a segnalare odori di design quando vengono richieste review di interfacce e implementazioni.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.

AspettoAudit manualeApplicazione automatica
AccuratezzaAlta per questioni contestualiCoerente per regole definite
CoerenzaVaria a seconda del reviewerStesse regole applicate ovunque
VelocitàLento per codebase grandiVeloce, 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 coppia migliora i workflow TDD perché interfacce più piccole sono più semplici da mockare e testare—supportando cicli Red-Green-Refactor più veloci e test unitari più chiari.5

ISP e sviluppo guidato dall'AI

Man mano che l'AI diventa più integrata nei workflow di sviluppo, interfacce chiare aiutano strumenti come i modelli stile GPT a ragionare sul codice. Interfacce piccole e mirate riducono l'ambiguità e migliorano la qualità del codice generato, dei suggerimenti automatici di refactor e della documentazione.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.

Domande comuni sull'ISP

ISP significa che ogni metodo ha bisogno della propria interfaccia?

No. L'obiettivo non è creare interfacce monometodo ovunque. Raggruppa i metodi che vengono sempre usati insieme dallo stesso client. Lo scopo è avere interfacce focalizzate e coese, non frammentarle.

In cosa l'ISP è diverso dal Principio di Responsabilità Singola?

SRP riguarda le classi e dice che una classe dovrebbe avere una sola ragione di cambiamento. ISP riguarda le interfacce e dice che i client non dovrebbero dipendere da metodi che non usano. Puoi rispettare SRP e comunque violare ISP se una classe implementa un'interfaccia gonfia.

Quando è accettabile ignorare l'ISP?

Principalmente quando non puoi cambiare l'interfaccia—librerie di terze parti o API legacy che non possiedi. Inoltre, se ogni client ha realmente bisogno di tutti i metodi, un'interfaccia più ampia può comunque essere coesa e accettabile.


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.

Tre Q&A concise (Domande comuni degli sviluppatori)

Q: Come riconosco velocemente una violazione ISP?

A: Cerca interfacce con molti metodi non correlati, classi con implementazioni vuote o che lanciano errori, o componenti con decine di props opzionali. Sono segnali forti che un contratto dovrebbe essere spezzato.

Q: Qual è il modo più veloce per sistemare una "fat interface"?

A: Identifica i ruoli distinti dei client, crea interfacce specifiche per ruolo e aggiorna le implementazioni affinché implementino solo ciò che serve. Esegui il cambiamento in modo incrementale per ridurre i rischi.

Q: Come prevengo 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.


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.

1.
Robert C. Martin ("Uncle Bob"), panoramica sui principi SOLID. [https://blog.cleancoder.com/]
2.
TypeScript handbook — Discriminated unions and advanced types. [https://www.typescriptlang.org/docs/handbook/2/advanced-types.html#discriminated-unions]
3.
Documentazione ESLint e guide per regole custom. [https://eslint.org/docs/latest/]
4.
GitHub Copilot e assistenti di coding basati su AI — esempi e linee guida. [https://github.com/features/copilot]
5.
Martin Fowler — Refactoring and testing practices. [https://martinfowler.com/]
← Back to blog
🙋🏻‍♂️

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.