Patrons de conception en C# : guide complet avec exemples
Les patrons de conception (Design Patterns) sont des solutions éprouvées aux problèmes typiques rencontrés lors du développement logiciel. Dans l'écosystème .NET et C#, la connaissance des patrons est particulièrement importante car beaucoup d'entre eux sont intégrés directement dans la plateforme (par exemple, IDisposable pour le patron Dispose). Dans cet article, nous allons examiner les trois principaux groupes de patrons selon la classification GoF (Gang of Four) avec des exemples pratiques en C#.
Patrons de création (Creational Patterns)
Les patrons de création sont responsables de la création d'objets, rendant le système indépendant de la manière dont ils sont créés, composés et représentés.
Singleton
Garantit qu'une classe n'a qu'une seule instance et fournit un point d'accès global à celle-ci. En C#, il est souvent utilisé pour travailler avec des loggers, un cache ou une configuration.
public sealed class Logger{ private static readonly Lazy<Logger> _instance = new Lazy<Logger>(() => new Logger());
public static Logger Instance => _instance.Value;
private Logger() { }
public void Log(string message) { Console.WriteLine($"[{DateTime.Now}] {message}"); }}
// UtilisationLogger.Instance.Log("Application démarrée");Factory Method (Méthode de fabrique)
Définit une interface pour créer un objet, mais permet aux sous-classes de modifier le type d'objet créé. Idéal pour une logique qui doit être extensible.
public interface ITransport{ void Deliver();}
public class Truck : ITransport{ public void Deliver() => Console.WriteLine("Livraison par route");}
public class Ship : ITransport{ public void Deliver() => Console.WriteLine("Livraison par mer");}
public abstract class Logistics{ public abstract ITransport CreateTransport();
public void PlanDelivery() { var transport = CreateTransport(); transport.Deliver(); }}
public class RoadLogistics : Logistics{ public override ITransport CreateTransport() => new Truck();}
public class SeaLogistics : Logistics{ public override ITransport CreateTransport() => new Ship();}
// UtilisationLogistics logistics = new RoadLogistics();logistics.PlanDelivery(); // Livraison par routePatrons structurels (Structural Patterns)
Les patrons structurels définissent des moyens de construire des classes et des objets pour former des structures plus grandes.
Adapter (Adaptateur)
Convertit l'interface d'une classe en une autre interface attendue par le client. Souvent utilisé pour l'intégration avec des bibliothèques tierces ou du code hérité.
// Interface cible (ITarget)public interface IXmlParser{ string ParseToXml(string data);}
// Classe adaptable (Adaptee)public class JsonParser{ public string ParseToJson(string data) { return $"{{\\"data\\": \\"{data}\\"}}"; }}
// Adaptateurpublic class JsonToXmlAdapter : IXmlParser{ private readonly JsonParser _jsonParser;
public JsonToXmlAdapter(JsonParser jsonParser) { _jsonParser = jsonParser; }
public string ParseToXml(string data) { var json = _jsonParser.ParseToJson(data); // Conversion JSON en XML très simple return $"<data>{data}</data>"; }}
// Utilisationvar adapter = new JsonToXmlAdapter(new JsonParser());string xml = adapter.ParseToXml("Hello");Console.WriteLine(xml); // <data>Hello</data>Decorator (Décorateur)
Ajoute dynamiquement de nouvelles responsabilités à un objet. En C#, ce patron est souvent implémenté via l'héritage ou la composition.
public interface INotifier{ void Send(string message);}
public class E