I design pattern sono un insieme di soluzioni ben collaudate per risolvere problemi di progettazione software comuni. Sono stati originariamente concepiti da Christopher Alexander e da un gruppo di architetti e ingegneri del software nel 1977, e sono stati successivamente formalizzati da Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides nel libro “Design Patterns: Elements of Reusable Object-Oriented Software” del 1994.
I design pattern sono spesso descritti come “ricette” per la progettazione del software, poiché forniscono un modello di soluzione che può essere riutilizzato in diverse situazioni. Sono utilizzati per risolvere problemi di progettazione comuni in modo efficace, garantendo una maggiore qualità del software e una maggiore flessibilità nel cambiamento.
Esistono diversi tipi di design pattern, come i pattern di creazione, di struttura e di comportamento, che possono essere utilizzati a seconda delle esigenze del progetto. L’utilizzo dei design pattern può avere alcuni svantaggi, come il rischio di utilizzare pattern non adeguati al problema o il rischio di creare soluzioni troppo complesse, ma in generale rappresentano uno strumento molto utile per la progettazione del software.

I diversi tipi di Design Pattern
I design pattern possono essere classificati in diverse categorie a seconda della loro funzione e della loro finalità.
Ecco alcune delle categorie più comuni:
- Design pattern di creazione: si occupano di come creare oggetti in modo che rispondano alle esigenze del progetto. Esempi di pattern di creazione sono il pattern Singleton, il pattern Factory e il pattern Prototype.
- Design pattern di struttura: si occupano di come organizzare e strutturare gli oggetti in modo da ottenere una determinata funzionalità. Esempi di pattern di struttura sono il pattern Adapter, il pattern Bridge e il pattern Composite.
- Design pattern di comportamento: si occupano di come gli oggetti interagiscono tra loro e di come si scambiano informazioni. Esempi di pattern di comportamento sono il pattern Strategy, Observer (publish-subscribe usato nell’architettura IOT), il pattern Visitor e il pattern Mediator.
- Design pattern di architettura: si occupano di come strutturare il software a livello di sistema per ottenere una determinata funzionalità. Esempi di pattern di architettura sono il pattern MVC (Model-View-Controller), il pattern Microservices e il pattern Client-Server.
- Design pattern di idioma: si occupano di come utilizzare al meglio le caratteristiche di un determinato linguaggio di programmazione. Esempi di pattern di idioma sono il pattern Iterator, il pattern Decorator e il pattern Template Method.
Strategy Pattern, esempio in c#
Il pattern Strategy è un design pattern di comportamento che consente di definire una famiglia di algoritmi, incapsularli e rendere facilmente intercambiabili tra loro. Questo pattern viene utilizzato per permettere a un oggetto di modificare il suo comportamento a runtime, senza dover modificare il suo codice sorgente.
Ecco un esempio di come lo Strategy Pattern possa essere implementato in C#:
// Crea l'interfaccia IStrategy che definisce il metodo Calculate()
public interface IStrategy
{
int Calculate(int a, int b);
}
// Creare le classi concrete che implementano l'interfaccia IStrategy
public class AdditionStrategy : IStrategy
{
public int Calculate(int a, int b)
{
return a + b;
}
}
public class SubtractionStrategy : IStrategy
{
public int Calculate(int a, int b)
{
return a - b;
}
}
// Creare la classe Context che utilizza l'interfaccia IStrategy
public class Context
{
private IStrategy _strategy;
public Context(IStrategy strategy)
{
_strategy = strategy;
}
public int Execute(int a, int b)
{
return _strategy.Calculate(a, b);
}
}
// Utilizzare la classe Context per eseguire l'algoritmo scelto
var context = new Context(new AdditionStrategy());
var result = context.Execute(5, 3); // il risultato sarà 8
context = new Context(new SubtractionStrategy());
result = context.Execute(5, 3); // il risultato sarà 2
In questo esempio, l’interfaccia IStrategy definisce il metodo Calculate() che viene implementato dalle classi concrete AdditionStrategy e SubtractionStrategy. La classe Context utilizza l’interfaccia IStrategy per eseguire l’algoritmo scelto, che può essere facilmente modificato a runtime passando un’istanza di una delle classi concrete al costruttore della classe Context. In questo modo, il comportamento della classe Context può essere modificato senza dover modificare il suo codice sorgente.