Design pattern: quelli che contano davvero (con esempi in Java)
Non i 23 pattern della Gang of Four recitati a memoria: i cinque che usiamo davvero in produzione, esempi in Java, quando un pattern è la scelta sbagliata, e perché i colloqui li chiedono ancora.
Michele Cimmino · CEO & Academy Director, Lasting Dynamics · 25 agosto 2026 · 6 min read
I design pattern hanno un problema di reputazione, e se lo sono meritato: generazioni di sviluppatori li hanno imparati come un catechismo — 23 nomi della Gang of Four da recitare al colloquio — e poi applicati a caso, producendo AbstractSingletonProxyFactoryBean e altre creature che nessuno voleva. In Lasting Dynamics i pattern li usiamo tutti i giorni e li insegniamo nella nostra academy, ma li insegniamo per quello che sono: vocabolario per problemi ricorrenti, non punti da collezionare.
Questa guida è la versione pratica: i pattern che usiamo davvero, esempi in Java, e — altrettanto importante — quando applicarne uno è l'errore.
Cosa sono davvero i design pattern
Un design pattern è una soluzione con un nome a un problema di progettazione che si ripresenta. Il valore non è la soluzione (che spesso è ovvia una volta vista): è il nome condiviso. Quando in review qualcuno dice "qui farei uno Strategy", il team trasferisce in tre parole un intero disegno. I pattern sono compressione di comunicazione prima che tecnica.
Corollario onesto: un pattern applicato dove il problema non esiste non è architettura — è costo. La domanda giusta non è mai "che pattern posso usare qui?" ma "che problema ho, e ha già un nome?".
I cinque che usiamo davvero
1. Strategy — quando l'algoritmo deve poter cambiare
Il pattern più utile in assoluto, e il più semplice: incapsula comportamenti intercambiabili dietro un'interfaccia.
interface PricingStrategy {
BigDecimal price(Order order);
}
class StandardPricing implements PricingStrategy { /* ... */ }
class BlackFridayPricing implements PricingStrategy { /* ... */ }
class Checkout {
private final PricingStrategy pricing;
Checkout(PricingStrategy pricing) { this.pricing = pricing; }
}
Ogni if (tipo == X) ... else if (tipo == Y) che cresce a ogni sprint è uno Strategy che chiede di nascere. In Java moderno spesso basta una lambda o un Function<Order, BigDecimal> — il pattern è l'idea, non la gerarchia di classi.
2. Factory Method — quando la creazione è una decisione
Se costruire un oggetto richiede logica (quale implementazione? con quali dipendenze?), quella logica merita un posto solo:
class NotifierFactory {
Notifier forChannel(Channel c) {
return switch (c) {
case EMAIL -> new EmailNotifier(smtp);
case SMS -> new SmsNotifier(twilio);
case PUSH -> new PushNotifier(fcm);
};
}
}
Il beneficio vero: il codice cliente dipende da Notifier, mai dai concreti. È il fratello operativo della dependency inversion di cui parliamo nella guida alla clean architecture.
3. Observer — quando qualcosa succede e altri devono saperlo
Eventi di dominio: l'ordine è confermato, e magazzino, email e analytics devono reagire — senza che Order conosca nessuno dei tre. In Java lo incontri più spesso tramite listener, eventi Spring o un message broker che come implementazione manuale, ma il disegno è lo stesso: chi emette non conosce chi ascolta. È il pattern che tiene basso l'accoppiamento nei sistemi che crescono.
4. Adapter — quando il mondo esterno non parla la tua lingua
Ogni integrazione seria ne ha uno: la libreria di pagamento ha la sua API, il tuo dominio ha la sua interfaccia, l'adapter traduce. Il valore strategico è il confine: quando il provider cambia API (lo farà), riscrivi l'adapter, non il dominio.
5. Decorator — quando aggiungi responsabilità senza toccare la classe
Logging, caching, retry attorno a un servizio esistente:
class CachedCatalog implements Catalog {
private final Catalog inner;
private final Map<String, Product> cache = new ConcurrentHashMap<>();
public Product byId(String id) {
return cache.computeIfAbsent(id, inner::byId);
}
}
Stessa interfaccia, comportamento arricchito, componibile a piacere. (È anche il disegno dietro mezzo ecosistema Java, dagli stream I/O ai middleware.)
Il pattern di cui diffidare: Singleton
Lo citiamo perché ai colloqui lo chiedono ancora: il Singleton garantisce una sola istanza globale. In pratica, nel 2026, è quasi sempre un segnale d'allarme — stato globale mascherato, test difficili, dipendenze nascoste. Se serve un'istanza sola, la crea il container di dependency injection (Spring lo fa di default, con scope singleton gestito, che è tutt'altra cosa). Saperlo spiegare a un colloquio vale più che saperlo implementare.
Quando un pattern è la scelta sbagliata
La regola che diamo in academy: prima il problema, poi il pattern — mai il contrario.
- Se il codice è più semplice senza il pattern, il pattern ha torto. Tre implementazioni di
PricingStrategydi cui due vuote sono uniftravestito. - I pattern si estraggono, non si anticipano: il momento giusto per lo Strategy è la seconda variante reale, non la prima immaginata.
- Se non sai spiegare quale cambiamento futuro il pattern protegge, stai facendo cerimonia.
E una nota per l'era degli agenti AI: strumenti come Claude Code generano pattern con entusiasmo — chiedigli una factory e ne avrai una bellissima, che serva o no. Il giudizio su se serve resta tuo. È lo stesso principio della guida al vibe coding: l'AI riempie la struttura; decidere la struttura è il mestiere.
Perché i colloqui li chiedono ancora (e come rispondere)
Perché sono un proxy rapido del vocabolario di progettazione. La risposta che colpisce non è l'elenco dei 23: è "qui userei uno Strategy perché questo if cresce a ogni sprint, e non userei un Singleton perché...". Il perché è il segnale; il nome è solo l'etichetta.
È esattamente come li alleniamo nella Lasting Dynamics Academy: i design pattern sono nel curriculum accanto ad architetture, RDBMS e testing, applicati su task reali e discussi nella review settimanale col mentore — dove "che pattern hai usato e perché" è una domanda vera, ogni settimana. Gratuita, full remote, a numero chiuso, con un'offerta di lavoro per chi completa. Se vuoi che il tuo vocabolario di progettazione diventi giudizio, le candidature sono aperte.
Domande frequenti
Devo impararli tutti e 23? No. Impara bene i cinque qui sopra più un paio che il tuo stack usa davvero (in Java: Builder e Template Method si incontrano spesso). Gli altri riconoscili quando li vedi; nessuno li usa tutti.
I design pattern valgono ancora con i linguaggi moderni?
Sì, ma molti si sono dissolti nel linguaggio: lambda al posto di Strategy formali, Optional al posto di Null Object, record per i value object. Il problema che il pattern risolveva esiste ancora; la soluzione è solo diventata più leggera. Riconoscere il problema resta la competenza.
Design pattern e architettura sono la stessa cosa? Scale diverse dello stesso istinto: i pattern organizzano classi e oggetti, l'architettura organizza moduli e confini. Un sistema può avere pattern perfetti e architettura pessima — e viceversa. Servono entrambi, ed è il motivo per cui in academy si studiano insieme.