- Patron Adaptateur
L'adaptateur sert d'intermédiaire pour rendre compatibles des interfaces incompatibles. Il existe deux variantes : l'adaptateur de classe et l'adaptateur d'objet.
Adaptateur de classe
// Interface cible
interface Cible {
void executer();
}
// Classe à adapter
class Source {
void operationSpecifique() {
System.out.println("Opération spécifique de la Source");
}
}
// Adaptateur de classe
class AdaptateurDeClasse extends Source implements Cible {
@Override
public void executer() {
operationSpecifique();
}
}
// Code client
public class Application {
public static void main(String[] args) {
Cible adapteur = new AdaptateurDeClasse();
adapteur.executer();
}
}
Adaptateur d'objet
// Interface cible
interface Cible {
void executer();
}
// Classe à adapter
class Source {
void operationSpecifique() {
System.out.println("Opération spécifique de la Source");
}
}
// Adaptateur d'objet
class AdaptateurDObjet implements Cible {
private Source source;
public AdaptateurDObjet(Source source) {
this.source = source;
}
@Override
public void executer() {
source.operationSpecifique();
}
}
// Code client
public class Application {
public static void main(String[] args) {
Source source = new Source();
Cible adapteur = new AdaptateurDObjet(source);
adapteur.executer();
}
}
- Patron Pont
Ce patron sépare l'abstraction de son implémentation, permettant aux deux d'évoluer indépendamment. Il utilise une composition pour lier les deux hiérarchies.
// Interface d'implémentation
interface Implementation {
void operationImpl();
}
// Implémentation concrète A
class ImplementationA implements Implementation {
@Override
public void operationImpl() {
System.out.println("Opération de ImplementationA");
}
}
// Implémentation concrète B
class ImplementationB implements Implementation {
@Override
public void operationImpl() {
System.out.println("Opération de ImplementationB");
}
}
// Abstraction
abstract class Abstraction {
protected Implementation impl;
public Abstraction(Implementation impl) {
this.impl = impl;
}
public abstract void operation();
}
// Abstraction étendue
class AbstractionEtendue extends Abstraction {
public AbstractionEtendue(Implementation impl) {
super(impl);
}
@Override
public void operation() {
System.out.println("Opération de l'abstraction étendue");
impl.operationImpl();
}
}
// Code client
public class Application {
public static void main(String[] args) {
Implementation implA = new ImplementationA();
Abstraction abstrA = new AbstractionEtendue(implA);
abstrA.operation();
Implementation implB = new ImplementationB();
Abstraction abstrB = new AbstractionEtendue(implB);
abstrB.operation();
}
}
- Patron Composite
Il permet de traiter uniformément les objets individuels et les compositions d'objets, formant des structures arborescentes avec des nœuds feuilles et composites.
// Interface composant
interface Composant {
void operation();
}
// Classe feuille
class Feuille implements Composant {
private String identifiant;
public Feuille(String identifiant) {
this.identifiant = identifiant;
}
@Override
public void operation() {
System.out.println("Opération de la feuille " + identifiant);
}
}
// Classe composite
class Composite implements Composant {
private List<composant> enfants = new ArrayList<>();
public void ajouter(Composant composant) {
enfants.add(composant);
}
public void supprimer(Composant composant) {
enfants.remove(composant);
}
@Override
public void operation() {
for (Composant composant : enfants) {
composant.operation();
}
}
}
// Code client
public class Application {
public static void main(String[] args) {
Composant feuille1 = new Feuille("X");
Composant feuille2 = new Feuille("Y");
Composant feuille3 = new Feuille("Z");
Composite compositeRacine = new Composite();
compositeRacine.ajouter(feuille1);
compositeRacine.ajouter(feuille2);
Composite sousComposite = new Composite();
sousComposite.ajouter(feuille3);
compositeRacine.ajouter(sousComposite);
compositeRacine.operation();
}
}
</composant>
- Patron Décorateur
Il ajoute dynamiquement des responsabilités à un objet sans modifier son code. Le décorateur enveloppe l'objet original et étend son comportement.
// Interface composant
interface Boisson {
String getDescription();
double cout();
}
// Composant concret
class CafeSimple implements Boisson {
@Override
public String getDescription() {
return "Café simple";
}
@Override
public double cout() {
return 1.0;
}
}
// Décorateur abstrait
abstract class DecorateurBoisson implements Boisson {
protected Boisson boissonDecoree;
public DecorateurBoisson(Boisson boissonDecoree) {
this.boissonDecoree = boissonDecoree;
}
public String getDescription() {
return boissonDecoree.getDescription();
}
public double cout() {
return boissonDecoree.cout();
}
}
// Décorateur concret pour le lait
class DecorateurLait extends DecorateurBoisson {
public DecorateurLait(Boisson boissonDecoree) {
super(boissonDecoree);
}
@Override
public String getDescription() {
return boissonDecoree.getDescription() + ", Lait";
}
@Override
public double cout() {
return boissonDecoree.cout() + 0.5;
}
}
// Code client
public class Application {
public static void main(String[] args) {
Boisson cafe = new CafeSimple();
System.out.println(cafe.getDescription() + " coûte $" + cafe.cout());
Boisson cafeLait = new DecorateurLait(cafe);
System.out.println(cafeLait.getDescription() + " coûte $" + cafeLait.cout());
}
}
- Patron Façade
Il fournit une interface simplifiée pour un ensemble di'nterfaces dans un sous-système, masquant la complexité interne et réduisant le couplage.
// Classe du sous-système A
class SousSystemeA {
public void actionA() {
System.out.println("Action du SousSystemeA");
}
}
// Classe du sous-système B
class SousSystemeB {
public void actionB() {
System.out.println("Action du SousSystemeB");
}
}
// Classe du sous-système C
class SousSystemeC {
public void actionC() {
System.out.println("Action du SousSystemeC");
}
}
// Classe façade
class Facade {
private SousSystemeA sousSystemeA;
private SousSystemeB sousSystemeB;
private SousSystemeC sousSystemeC;
public Facade() {
sousSystemeA = new SousSystemeA();
sousSystemeB = new SousSystemeB();
sousSystemeC = new SousSystemeC();
}
public void operationGlobale() {
System.out.println("Opération via la façade");
sousSystemeA.actionA();
sousSystemeB.actionB();
sousSystemeC.actionC();
}
}
// Code client
public class Application {
public static void main(String[] args) {
Facade facade = new Facade();
facade.operationGlobale();
}
}
- Patron Flyweight
Il optimise la mémoire en partageant des objets similaires. Un objet flyweight partage un état intrinsèque, tandis que l'état extrinsèque est passé lors des appels.
import java.util.Map;
import java.util.HashMap;
// Fabrique flyweight
class FabriqueFlyweight {
private Map<string flyweight=""> pool = new HashMap<>();
public Flyweight obtenirFlyweight(String cle) {
Flyweight flyweight = pool.get(cle);
if (flyweight == null) {
flyweight = new FlyweightConcret(cle);
pool.put(cle, flyweight);
}
return flyweight;
}
}
// Interface flyweight
interface Flyweight {
void operation();
}
// Classe flyweight concrète
class FlyweightConcret implements Flyweight {
private String cle;
public FlyweightConcret(String cle) {
this.cle = cle;
}
@Override
public void operation() {
System.out.println("Opération du Flyweight " + cle);
}
}
// Code client
public class Application {
public static void main(String[] args) {
FabriqueFlyweight fabrique = new FabriqueFlyweight();
Flyweight fw1 = fabrique.obtenirFlyweight("alpha");
fw1.operation();
Flyweight fw2 = fabrique.obtenirFlyweight("beta");
fw2.operation();
Flyweight fw3 = fabrique.obtenirFlyweight("alpha");
fw3.operation();
}
}
</string>
- Patron Proxy
Il contrôle l'accès à un objet en fournissant un substitut. Le proxy peut gérer des fonctions comme l'accès distant, la protection ou la mise en cache.
// Interface sujet
interface Sujet {
void traiterRequete();
}
// Classe sujet réelle
class SujetReel implements Sujet {
@Override
public void traiterRequete() {
System.out.println("SujetReel : Traitement de la requête");
}
}
// Classe proxy
class Proxy implements Sujet {
private SujetReel sujetReel;
public Proxy() {
this.sujetReel = new SujetReel();
}
@Override
public void traiterRequete() {
System.out.println("Proxy : Journalisation de la requête");
sujetReel.traiterRequete();
System.out.println("Proxy : Post-traitement");
}
}
// Code client
public class Application {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.traiterRequete();
}
}