Pattern État PowerPoint 2003, télécharger la visionneuse PowerPoint Viewer dernière édition si...
-
Upload
raphael-bailly -
Category
Documents
-
view
110 -
download
3
Transcript of Pattern État PowerPoint 2003, télécharger la visionneuse PowerPoint Viewer dernière édition si...
Pattern État PowerPoint 2003, télécharger la visionneuse PowerPoint Viewer dernière édition si vous ne l’avez pas…
EtatConcretChaque sous-classe
implémente un comportement associé avec l’état de
contexte.
Définition :Le pattern état permet à un objet de modifier son
comportement quand son état interne change.
Tout se passera comme si l’objet changeait de classe.
<<abstract>>Etat
+méthode1()+méthode2()+méthode3()+méthode4()
EtatConcret
+méthode1()+méthode2()+méthode3()+méthode4()
EtatConcret
+méthode1()+méthode2()+méthode3()+méthode4()
EtatConcret
+méthode1()+méthode2()+méthode3()+méthode4()
EtatConcret
+méthode1()+méthode2()+méthode3()+méthode4()
Contexte
+méthode1()+méthode2()+méthode3()+méthode4()
Contexte- Définit l’interface intéressant les clients.- Gère une instance d’une sous-classe EtatConcret qui définit l’état en cours.
Etat -Définit une interface qui
encapsule le comportement associé avec un état en particulier de contexte.
Machine à bonbons
Pas depièce
A unepièce
Bonbonvendu
Plus de bonbons
Remplir
Insé
rer p
ièce
éjecte
r pièc
e
Tourner poignée
délivrer bonbon
Bonbon > 0
Bonbon = 0
Une méthode par action
Variable d’instance d’état courant
Voici les 4 états
Constructeur
Bloc conditionnelle servant à tester
les états
Public class Distributeur {
final static int EPUISE = 0;final static int SANS_PIECE = 1;final static int A_PIECE = 2;final static int VENDU = 3;
int etat = EPUISE;int nombre = 0;
public Distributeur (int nombre) {this.nombre = nombre;if (nombre > 0) { etat = SANS_PIECE;}
}
public void insererPiece() {if (etat == A_PIECE) { System.out.println("Vous ne pouvez plus inséré de pièces");} else if (etat == SANS_PIECE) {
etat = A_PIECE;System.out.println("Vous avez inséré une pièce");
} else if (etat == EPUISE) {System.out.println("Rupture de stock, ne pas insérer de
pièce");} else if (etat == VENDU) {
System.out.println(« Veuillez patienter, le bonbon va tomber");}
}
public void ejecterPiece() { … … }
public void tournerPoignee() { …… }
public void delivrer() { … … }
…}
Public class TestDisributeur {
public static void main (String[ ] args) {
Distributeur distributeur = new Distributeur(5);
distributeur.insererPiece();distributeur.tournerPoignee();
distributeur.insererPiece();distributeur.ejecterPiece();distributeur.tournerPoignee();
distributeur.insererPiece();distributeur.tournerPoignee();distributeur.insererPiece();distributeur.tournerPoignee();distributeur.ejecterPiece();
%java TestDistributeur
Vous avez inséré une pièce
Vous avez tourné…
Un bonbon va sortir…
System.out.println(distributeur);
System.out.println(distributeur);
System.out.println(distributeur);
System.out.println(distributeur);
Stock 5 bonbons
L’appareil attend une pièce
Stock 4 bonbons
L’appareil attend une pièce
Vous avez inséré une pièce
Pièce retournée
Vous avez tourné mais il n’y a pas de pièce
Il faut payer d’abord
Stock 4 bonbons
L’appareil attend une pièce
Vous avez inséré une pièce
Vous avez tourné...
Un bonbon va sortir...
Vous avez inséré une pièce
Vous avez tourné...
Un bonbon va sortir...
Vous n'avez pas inséré de pièce
Stock 2 bonbons
L’appareil attend une pièce
…
Public class TestDisributeur {
public static void main (String[ ] args) {
Distributeur distributeur = new Distributeur(5);
distributeur.insererPiece();distributeur.tournerPoignee();
distributeur.insererPiece();distributeur.ejecterPiece();distributeur.tournerPoignee();
distributeur.insererPiece();distributeur.tournerPoignee();distributeur.insererPiece();distributeur.tournerPoignee();distributeur.ejecterPiece();
distributeur.insererPiece();distributeur.insererPiece();distributeur.tournerPoignee();distributeur.insererPiece();distributeur.tournerPoignee();distributeur.insererPiece();distributeur.tournerPoignee();
Vous avez inséré une pièce
Vous ne pouvez pas insérer d'autres pièces
Vous avez tourné...
Un bonbon va sortir...
Vous avez inséré une pièce
Vous avez tourné...
Un bonbon va sortir...
Aïe, plus de bonbons !
Vous ne pouvez pas insérer de pièce, nous sommes en rupture de stock
Vous avez tourné, mais il n'y a pas de bonbons
Pas de bonbon délivré
System.out.println(distributeur);
System.out.println(distributeur);
System.out.println(distributeur);
System.out.println(distributeur);
System.out.println(distributeur);
Stock 2 bonbons
L’appareil attend une pièce
Stock 0 bonbons
L’appareil est en rupture de stock
…
Indication d’utilisation• Le comportement d’un objet dépend de son état, et ce changement de comportement doit intervenir
dynamiquement • Les opérations comportent de grand pans entiers de déclarations conditionnelles en fonctions de l’états de l’objet.
Cet état est généralement désigné par une ou plusieurs constantes d’énumération. Souvent, plusieurs opérations différentes, contiendront la même structure conditionnelle.
public void insererPiece() { if (etat == A_PIECE) {
… } else if (etat == SANS_PIECE) {
… } else if (etat == EPUISE) {
… } else if (etat == VENDU) {
… }}
public void ejecterPiece() { if (etat == A_PIECE) {
… } else if (etat == SANS_PIECE) {
… } else if (etat == EPUISE) {
… } else if (etat == VENDU) {
… }}
public void tournerPoignee() { if (etat == A_PIECE) {
… } else if (etat == SANS_PIECE) {
… } else if (etat == EPUISE) {
… } else if (etat == VENDU) {
… }}
Le modèle état place dans une classe séparée, chacune des branches de la condition.
Ceci permet de traiter l’état de l’objet, comme un objet à part entière,
qui peut varier indépendamment des autres objets.
Public class etatPiece { … } Public class etatEpuiser { … } Public class etatVendu { … } Public class etatSensPiece { … }
Public interface etat { … }
<<interface>>public interface Etat {
public void insererPiece();public void ejecterPiece();public void tournerPoignee();public void delivrer();
}
<<interface>>public interface Etat {
public void insererPiece();public void ejecterPiece();public void tournerPoignee();public void delivrer();
}
public class EtatAPiece implements Etat { Distributeur distributeur public EtatAPiece(Distributeur distributeur) { this.distributeur = distributeur; } public void insererPiece() { System.out.println("Vous ne pouvez pas insérer d'autre pièce"); }
public void ejecterPiece() { System.out.println("Pièce retournée"); distributeur.setEtat(distributeur.getEtatSansPiece()); } public void tournerPoignee() { System.out.println("Vous avez tourné..."); distributeur.setEtat(distributeur.getEtatVendu()); } public void delivrer() { System.out.println("Pas de bonbon délivré"); }}
public class EtatAPiece implements Etat { Distributeur distributeur public EtatAPiece(Distributeur distributeur) { this.distributeur = distributeur; } public void insererPiece() { System.out.println("Vous ne pouvez pas insérer d'autre pièce"); }
public void ejecterPiece() { System.out.println("Pièce retournée"); distributeur.setEtat(distributeur.getEtatSansPiece()); } public void tournerPoignee() { System.out.println("Vous avez tourné..."); distributeur.setEtat(distributeur.getEtatVendu()); } public void delivrer() { System.out.println("Pas de bonbon délivré"); }}
public class EtatEpuise implements Etat { Distributeur distributeur; public EtatEpuise(Distributeur distributeur) { this.distributeur = distributeur; } public void insererPiece() { System.out.println("Vous ne pouvez pas insérer de pièce,
nous sommes en rupture de stock"); } public void ejecterPiece() { System.out.println("Ejection impossible,
vous n'avez pas inséré de pièce"); } public void tournerPoignee() { System.out.println("Vous avez tourné,
mais il n'y a pas de bonbons"); } public void delivrer() { System.out.println("Pas de bonbon délivré"); }}
public class EtatEpuise implements Etat { Distributeur distributeur; public EtatEpuise(Distributeur distributeur) { this.distributeur = distributeur; } public void insererPiece() { System.out.println("Vous ne pouvez pas insérer de pièce,
nous sommes en rupture de stock"); } public void ejecterPiece() { System.out.println("Ejection impossible,
vous n'avez pas inséré de pièce"); } public void tournerPoignee() { System.out.println("Vous avez tourné,
mais il n'y a pas de bonbons"); } public void delivrer() { System.out.println("Pas de bonbon délivré"); }}
Implémentation de l’interface Etat
et des classes EtatConcret
Implémentation de l’interface Etat
et des classes EtatConcret
Distributeur
insererPiece()ejecterPiece()tournerPoignee()remplir(…)setEtat(…)liberer()
…
EtatEpuise
insererPiece()ejecterPiece()tournerPoignee()delivrer()
EtatSansPiece
insererPiece()ejecterPiece()tournerPoignee()delivrer()
EtatAPiece
insererPiece()ejecterPiece()tournerPoignee()delivrer()
EtatVendu
insererPiece()ejecterPiece()tournerPoignee()delivrer()
<<interface>>Etat
insererPiece()ejecterPiece()tournerPoignee()delivrer()
Transformation de la classe Distributeur
Public class Distributeur {
final static int EPUISE = 0;final static int SANS_PIECE = 1;final static int A_PIECE = 2;final static int VENDU = 3;
int etat = EPUISE;int nombre = 0;
public Distributeur (int nombre) { this.nombre = nombre; if (nombre > 0) { etat = SANS_PIECE; }}
public class Distributeur {
Etat etatEpuise; Etat etatSansPiece; Etat etatAPiece; Etat etatVendu; Etat etat = etatEpuise; int nombre = 0;
public Distributeur(int nombreBonbons) { etatEpuise = new EtatEpuise(this); etatSansPiece = new EtatSansPiece(this); etatAPiece = new EtatAPiece(this); etatVendu = new EtatVendu(this); this.nombre = nombreBonbons; if (nombreBonbons > 0) { etat = etatSansPiece; } }
L’objet distributeur crée les objets état et les instancie dans son constructeur, puis la variable etat contiendra une référence vers l’état d’origine, soit SansPiece, soit Epuiser, suivant qu’il est rempli ou vide
Etats du Distributeur
SansPiece
APiece
Vendu
Epuiser
Distributeur.etat
public void insererPiece() {etat.insererPiece();
}public void ejecterPiece() {
etat.ejecterPiece();}public void tournerPoignee() {
etat.tournerPoignee();etat.delivrer();
}
void setEtat(Etat etat) { this.etat = etat;}
public Etat getEtatSansPiece() { return this.etatSansPiece;}
public Etat getEtatVendu() { return this.etatVendu;}
public Etat getEtatAPiece() { return this.etatAPiece;}
public Etat getEtatEpuise() { return this.etatEpuise;}
public int getNombre() { return this.nombre;}
public String toString() { return "\nDistribonbon, SARL.\n Distributeur compatible Java, modèle 2007 \n Stock "+ nombre +" bonbons \n"+ ((nombre > 0)? "L'appareil attand une piece\n": "L'appareil est en rupture de stock\n") ;
void liberer() { System.out.println("Un Bonbon va sortir..."); if (nombre != 0) { nombre = nombre -1; }}
Void remplir(int nombre) {
this.nombre = nombre;
etat = etatSansPiece;
}
On remarque que le contexte, ici le distributeur,Peut aussi changer son état.
=> L’état peut être changé soit :-Dans les états concrets
- Dans le contexte
public void tournerPoignee() {
etat.tournerPoignee();
etat.delivrer();
}
Etats du Distributeur
SansPiece
APiece
Vendu
Epuiser
tournerPoignee()
etatAPiece
public void tournerPoignee() { System.out.println("Vous avez tourné..."); distributeur.setEtat(distributeur.getEtatVendu());}
Vous avez tourné…
Un bonbon va sortir
etatVendu
public void delivrer() { distributeur.liberer(); if (distributeur.getNombre() > 0) { distributeur.setEtat(distributeur.getEtatSansPiece()); } else { System.out.println("A‹e, plus de bonbons !"); distributeur.setEtat(distributeur.getEtatEpuise()); }}
etat tournerPoignee()
Delivrer()
Nombre = 5Nombre = 4
Distributeur
- rend le code plus lisible car il enlève les grandes déclarations de type conditionnel qui ne sont pas souhaitables car elles ont un éffet monolithique qui à tendance à rendre le code moins explicite
- rend les transitions d’état plus explicite car il introduit des objets distincts pour chaque état
Exemple prit dans le livre :
Voir le site Tête la première OU voir le site O’Reilly