Vous êtes sur la page 1sur 24

Sommaire

Visitor 3
Principe 3
UML 4
Exemple Concret 4
On définit une interface qui représente un élément. 4
On crée les classes qui étendent cette interface. 4
On crée une interface qui représente Visitor. 5
On crée deux classes visitor qui étendent l'interface précédente. 6
On crée une classe de test pour la démonstration grâce aux deux classes précédentes. 7
Avantage et Inconvénient 7

Builder 8
Principe 8
UML 8
Exemple Concret 9

Command 12
Principe 12
UML 12
Exemple Concret 13
Avantage et Inconvénient 15
Avantage et Inconvénient 15

Observer 16
Principe 16
UML 16
Exemple Concret 17
Avantage et Inconvénient 17

Factory Method 18
Principe 18
UML 18
Exemple Concret 19
Avantage et Inconvénient 20

Memento 21
Principe 21
UML 21
Exemple Concret 22
Créez une classe Memento 22
Créer une classe Originator 22
Créer une classe CareTaker 23
Utilisez les objets CareTaker et Originator 23
Vérifiez la sortie 24
Avantage et Inconvénient 24

3 type de Design Pattern : Structurel, comportemental, création


Visitor
Principe
interface MonVisiteur {
void visit(Objet1 objet);
void visit(Objet2 objet);
void visit(Objet3 objet);
}

interface ObjetPere {
void accept(MonVisiteur v);
}

public class Objet1 implements ObjetPere {


public void accept(MonVisiteur v) {
v.visit(this);
}
}

public class Objet2 implements ObjetPere {


public void accept(MonVisiteur v) {
v.visit(this);
}
}

public class Objet3 implements ObjetPere {


public void accept(MonVisiteur v) {
v.visit(this);
}
}
UML

Exemple Concret
On définit une interface qui représente un élément.
interface CarElement {
void accept(CarElementVisitor visitor);
// Méthode à définir par les classes implémentant CarElements
}

On crée les classes qui étendent cette interface.


class Wheel implements CarElement {
private String name;

Wheel(String name) {
this.name = name;
}

String getName() {
return this.name;
}

public void accept(CarElementVisitor visitor) {


visitor.visit(this);
}
}

class Engine implements CarElement {


public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}

class Body implements CarElement {


public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}

class Car {
CarElement[] elements;

public CarElement[] getElements() {


return elements.clone(); // Retourne une copie du tableau de
références
}

public Car() {
this.elements = new CarElement[] {
new Wheel("front left"),
new Wheel("front right"),
new Wheel("back left"),
new Wheel("back right"),
new Body(),
new Engine()
};
}
}

On crée une interface qui représente Visitor.


public interface CarElementVisitor {
void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visitCar(Car car);
}
On crée deux classes visitor qui étendent l'interface précédente.
class CarElementPrintVisitor implements CarElementVisitor {
public void visit(Wheel wheel) {
System.out.println("Visiting "+ wheel.getName() + " wheel");
}

public void visit(Engine engine) {


System.out.println("Visiting engine");
}

public void visit(Body body) {


System.out.println("Visiting body");
}

public void visitCar(Car car) {


System.out.println("\nVisiting car");
for(CarElement element : car.getElements()) {
element.accept(this);
}
System.out.println("Visited car");
}
}

class CarElementDoVisitor implements CarElementVisitor {


public void visit(Wheel wheel) {
System.out.println("Kicking my "+ wheel.getName());
}

public void visit(Engine engine) {


System.out.println("Starting my engine");
}

public void visit(Body body) {


System.out.println("Moving my body");
}

public void visitCar(Car car) {


System.out.println("\nStarting my car");
for(CarElement carElement : car.getElements()) {
carElement.accept(this);
}
System.out.println("Started car");
}
}
On crée une classe de test pour la démonstration grâce aux deux
classes précédentes.
public class TestVisitorDemo {
static public void main(String[] args) {
Car car = new Car();

CarElementVisitor printVisitor = new


CarElementPrintVisitor();
CarElementVisitor doVisitor = new CarElementDoVisitor();

printVisitor.visitCar(car);
doVisitor.visitCar(car);
}
}

Avantage et Inconvénient

Avantage Inconvénient

Principe ouvert / fermé. Vous pouvez Vous devez mettre à jour tous les
introduire un nouveau comportement qui visiteurs chaque fois qu'une classe est
peut fonctionner avec des objets de ajoutée ou supprimée de la hiérarchie
différentes classes sans changer ces des éléments.
classes.

Principe de responsabilité unique. Vous Les visiteurs peuvent ne pas avoir accès
pouvez déplacer plusieurs versions du aux champs privés et aux méthodes des
même comportement dans la même éléments avec lesquels ils sont censés
classe. travailler.

Un objet visiteur peut accumuler des


informations utiles tout en travaillant
avec divers objets. Cela peut être
pratique lorsque vous souhaitez
parcourir une structure d'objet
complexe, telle qu'une arborescence
d'objets, et appliquer le visiteur à
chaque objet de cette structure.
Builder
Principe

Builder est un modèle de conception créative qui vous permet de construire des objets
complexes étape par étape. Le modèle vous permet de produire différents types et
représentations d'un objet en utilisant le même code de construction.

UML
Exemple Concret

public class User


{
//All final attributes
private final String firstName; // required
private final String lastName; // required
private final int age; // optional
private final String phone; // optional
private final String address; // optional

private User(UserBuilder builder) {


this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}

// Tout getter, et AUCUN setter pour prouver l'immuabilité


public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getPhone() {
return phone;
}
public String getAddress() {
return address;
}

@Override
public String toString() {
return "User: "+this.firstName+", "+this.lastName+",
"+this.age+", "+this.phone+", "+this.address;
}
}
public static class UserBuilder
{
private final String firstName;
private final String lastName;
private int age;
private String phone;
private String address;

public UserBuilder(String firstName, String lastName) {


this.firstName = firstName;
this.lastName = lastName;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public UserBuilder address(String address) {
this.address = address;
return this;
}
// Renvoie l'objet User finalement constuit
public User build() {
User user = new User(this);
validateUserObject(user);
return user;
}
private void validateUserObject(User user) {
// Faites quelques validations de base pour vérifier
// si l'objet utilisateur ne rompt aucune hypothèse de
système
}
}
}
public static void main(String[] args) {
User user1 = new User.UserBuilder("Lokesh", "Gupta")
.age(30)
.phone("1234567")
.address("Fake address 1234")
.build();

System.out.println(user1);

User user2 = new User.UserBuilder("Jack", "Reacher")


.age(40)
.phone("5655")
//no address
.build();

System.out.println(user2);

User user3 = new User.UserBuilder("Super", "Man")


//No age
//No phone
//no address
.build();

System.out.println(user3);
}

Output:

User: Lokesh, Gupta, 30, 1234567, Fake address 1234


User: Jack, Reacher, 40, 5655, null
User: Super, Man, 0, null, null

Avantage et Inconvénient
Avantage Inconvénient

Vous pouvez construire des objets étape La complexité globale du code augmente
par étape, différer les étapes de car le modèle nécessite la création de
construction ou exécuter des étapes de plusieurs nouvelles classes.
manière récursive.

Vous pouvez réutiliser le même code de


construction lors de la création de diverses
représentations de produits.

Principe de responsabilité unique . Vous


pouvez isoler le code de construction
complexe de la logique métier du produit.
Command
Principe

Commande est un modèle de conception comportementale qui transforme une


demande en un objet autonome contenant toutes les informations sur la demande.
Cette transformation vous permet de paramétrer des méthodes avec différentes
requêtes, de retarder ou de mettre en file d'attente l'exécution d'une requête et de
prendre en charge les opérations annulables.

UML
Exemple Concret

/*the Command interface*/


public interface Command {
void execute();
}

/*the Invoker class*/


public class SwitchManager {

private final HashMap<String, Command> commandMap = new


HashMap<>();
private List<Command> history = new ArrayList<Command>();

public void register(String commandName, Command command) {


commandMap.put(commandName, command);
}

public void execute(String cmdName) {


Command command = commandMap.get(cmdName);
if (command == null) {
throw new IllegalStateException("no command registered
for " + cmdName);
}
this.history.add(command); // optional
command.execute();
}
}

/*the Receiver class*/


public class Light {
public void turnOn() {
System.out.println("The light is on");
}

public void turnOff() {


System.out.println("The light is off");
}
}
/*the Command for turning on the light - ConcreteCommand #1*/
public class FlipUpCommand implements Command {

private Light light;

public FlipUpCommand(Light light) {


this.light = light;
}

@Override // Command
public void execute(){
this.light.turnOn();
}
}

/*the Command for turning off the light - ConcreteCommand #2*/


public class FlipDownCommand implements Command {

private Light light;

public FlipDownCommand(Light light) {


this.light = light;
}

@Override // Command
public void execute() {
this.light.turnOff();
}
}

/*The test class or client*/


public class PressSwitchDemo {

public static void main(String[] args){


Light lamp = new Light();
Command switchOn = new FlipUpCommand(lamp);
Command switchOff = new FlipDownCommand(lamp);

SwitchManager mySwitchManager = new SwitchManager();


mySwitchManager.register("on", switchOn);
mySwitchManager.register("off", switchOff);

mySwitchManager.execute("on");
mySwitchManager.execute("off");
}
}

Avantage et Inconvénient

Avantage Inconvénient

Principe de responsabilité unique . Vous Le code peut devenir plus compliqué


pouvez découpler les classes qui appellent puisque vous introduisez une toute nouvelle
des opérations des classes qui effectuent couche entre les expéditeurs et les
ces opérations. destinataires.

Principe ouvert / fermé . Vous pouvez


introduire de nouvelles commandes dans
l'application sans casser le code client
existant.

Vous pouvez implémenter annuler / rétablir.

Vous pouvez implémenter une exécution


différée des opérations.

Vous pouvez assembler un ensemble de


commandes simples en une commande
complexe.
Observer
Principe

Observer est un modèle de conception comportementale qui vous permet de définir


un mécanisme d'abonnement pour notifier plusieurs objets de tout événement
survenant à l'objet qu'ils observent.

UML
Exemple Concret

public class ONewsChannel implements Observer {

private String news;

@Override
public void update(Observable o, Object news) {
this.setNews((String) news);
}
}

public class ONewsAgency extends Observable {


private String news;

public void setNews(String news) {


this.news = news;
setChanged();
notifyObservers(news);
}
}

Avantage et Inconvénient

Avantage Inconvénient

Principe ouvert / fermé . Vous pouvez Les abonnés sont notifiés dans un ordre
introduire de nouvelles classes d'abonnés aléatoire.
sans avoir à changer le code de l'éditeur (et
vice versa s'il existe une interface éditeur).

Vous pouvez établir des relations entre les


objets lors de l'exécution.
Factory Method
Principe

La méthode Factory est un modèle de conception créative qui fournit une interface
pour créer des objets dans une superclasse, mais permet aux sous-classes de
modifier le type d'objets qui seront créés.

UML
Exemple Concret

Le MazeGame utilise des salles mais il confie la responsabilité de créer des salles à ses
sous-classes qui créent les classes concrètes. Le mode de jeu normal pourrait utiliser cette
méthode de modèle:

public abstract class Room {


abstract void connect(Room room);
}

public class MagicRoom extends Room {


public void connect(Room room) {}
}

public class OrdinaryRoom extends Room {


public void connect(Room room) {}
}

public abstract class MazeGame {


private final List<Room> rooms = new ArrayList<>();

public MazeGame() {
Room room1 = makeRoom();
Room room2 = makeRoom();
room1.connect(room2);
rooms.add(room1);
rooms.add(room2);
}

abstract protected Room makeRoom();


}
Dans l'extrait de code ci-dessus, le MazeGame constructeur est une méthode de
modèle qui crée une logique commune. Il fait référence à la makeRoom méthode
d'usine qui encapsule la création de pièces de sorte que d'autres pièces puissent être
utilisées dans une sous-classe. Pour implémenter l'autre mode de jeu qui a des salles
magiques, il suffit de remplacer la makeRoom méthode :

public class MagicMazeGame extends MazeGame {


@Override
protected Room makeRoom() {
return new MagicRoom();
}
}

public class OrdinaryMazeGame extends MazeGame {


@Override
protected Room makeRoom() {
return new OrdinaryRoom();
}
}

MazeGame ordinaryGame = new OrdinaryMazeGame();


MazeGame magicGame = new MagicMazeGame();

Avantage et Inconvénient

Avantage Inconvénient

Principe de responsabilité unique. Vous Le code peut devenir plus compliqué car
pouvez déplacer le code de création de vous devez introduire de nombreuses
produit en un seul endroit dans le nouvelles sous-classes pour implémenter le
programme, ce qui facilite la prise en modèle. Le meilleur des cas est lorsque
charge du code vous introduisez le modèle dans une
hiérarchie existante de classes de créateur.

Principe de responsabilité unique. Vous


pouvez déplacer le code de création de
produit en un seul endroit dans le
programme, ce qui facilite la prise en
charge du code

Vous évitez un couplage étroit entre le


créateur et les produits en béton.
Memento
Principe

Memento est un modèle de conception comportementale qui vous permet d'enregistrer


et de restaurer l'état précédent d'un objet sans révéler les détails de son
implémentation
Le modèle Memento utilise trois classes d'acteurs. Memento contient l'état d'un objet à
restaurer.
Originator crée et stocke des états dans des objets Memento et l'objet
Caretaker est chargé de restaurer l'état de l'objet à partir de Memento.
Nous avons créé des classes Memento , Originator et CareTaker .
MementoPatternDemo , notre classe de démonstration, utilisera les objets CareTaker
et Originator pour afficher la restauration des états des objets.

UML
Exemple Concret
Créez une classe Memento
public class Memento {
private String state;

public Memento(String state){


this.state = state;
}

public String getState(){


return state;
}
}

Créer une classe Originator


public class Originator {
private String state;

public void setState(String state){


this.state = state;
}

public String getState(){


return state;
}

public Memento saveStateToMemento(){


return new Memento(state);
}

public void getStateFromMemento(Memento memento){


state = memento.getState();
}
}
Créer une classe CareTaker
import java.util.ArrayList;
import java.util.List;

public class CareTaker {


private List<Memento> mementoList = new ArrayList<Memento>();

public void add(Memento state){


mementoList.add(state);
}

public Memento get(int index){


return mementoList.get(index);
}
}

Utilisez les objets CareTaker et Originator


public class MementoPatternDemo {
public static void main(String[] args) {

Originator originator = new Originator();


CareTaker careTaker = new CareTaker();

originator.setState("State #1");
originator.setState("State #2");
careTaker.add(originator.saveStateToMemento());

originator.setState("State #3");
careTaker.add(originator.saveStateToMemento());

originator.setState("State #4");
System.out.println("Current State: " + originator.getState());

originator.getStateFromMemento(careTaker.get(0));
System.out.println("First saved State: " +
originator.getState());
originator.getStateFromMemento(careTaker.get(1));
System.out.println("Second saved State: " +
originator.getState());
}
}
Vérifiez la sortie
Current State: State #4
First saved State: State #2
Second saved State: State #3

Avantage et Inconvénient

Avantage Inconvénient

Vous pouvez produire des instantanés de L'application peut consommer beaucoup de


l'état de l'objet sans violer son RAM si les clients créent trop souvent des
encapsulation. souvenirs.

Vous pouvez simplifier le code de La plupart des langages de programmation


l'expéditeur en permettant au gardien de dynamiques, tels que PHP, Python et
gérer l'historique de l'état de l'expéditeur. JavaScript, ne peuvent garantir que l'état
dans le memento reste intact.

Les gardiens doivent suivre le cycle de vie


du créateur pour être en mesure de détruire
les souvenirs obsolètes.

Vous aimerez peut-être aussi