0% ont trouvé ce document utile (0 vote)
63 vues43 pages

Clonage d'Objets avec Prototype en Java

Transféré par

ِAbdulsamad Tanafaat
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
63 vues43 pages

Clonage d'Objets avec Prototype en Java

Transféré par

ِAbdulsamad Tanafaat
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Design Pattern

Prototype
Le pattern Prototype est un modèle de conception créatif qui permet de créer
des objets en clonant des instances existantes au lieu de les créer à partir de
zéro.

Clonage d'Objets : Le Prototype utilise un mécanisme de clonage pour créer de


nouveaux objets. Cela peut être fait par une méthode de clonage qui copie les
propriétés de l'objet existant.
Simplicité : Simplifie la création d'objets à partir d'objets existants au lieu de
recourir à des constructeurs complexes.

Exemple d'Utilisation
Supposons que vous ayez une classe Document qui représente un document dans
un système. Au lieu de créer un nouveau document avec tous ses paramètres par
défaut, vous pouvez créer un document prototype et le cloner chaque fois que
vous avez besoin d'un nouveau document.
En Java, le clonage d'objets se fait généralement à l'aide de la méthode clone()
de la classe Object.

Types de Clonage

Clonage Superficiel (Shallow Copy) : Crée une copie d'un objet, mais ne copie pas les
objets référencés par cet objet. Les références aux objets d'origine et aux objets
clonés pointent vers le même objet.

Clonage Profond (Deep Copy) : Crée une copie complète d'un objet, y compris les
objets référencés. Les références dans l'objet cloné pointent vers de nouveaux objets.
La méthode clone() est déclarée dans la classe Object comme suit :
protected Object clone() throws CloneNotSupportedException

Pour que la méthode clone() fonctionne correctement, la classe doit implémenter


l'interface Cloneable. Si vous essayez de cloner un objet d'une classe qui
n'implémente pas Cloneable, une CloneNotSupportedException sera lancée.

La méthode clone() crée une copie superficielle de l'objet. Cela signifie que les
champs primitifs de l'objet sont copiés directement, tandis que les références aux
objets sont copiées, mais elles pointent vers les mêmes objets que l'original.
Clonage Profond (Deep Copy)

Le clonage profond (ou deep copy) class Address {


private String city;
consiste à créer une copie d'un objet
ainsi que de tous les objets qu'il public Address(String city) {
référence, assurant ainsi que les objets [Link] = city;
}
originaux et clonés sont entièrement
indépendants. public String getCity() {
return city;
}
Pour réaliser un clonage profond en
Java, vous pouvez suivre plusieurs public void setCity(String city) {
approches, notamment en [Link] = city;
}
implémentant la méthode clone() }
class Person implements Cloneable {
private String name;
private Address address; // Référence à un objet Address
public Person(String name, Address address) {
[Link] = name;
[Link] = address;
}
// Surcharge de la méthode clone pour un clonage profond
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) [Link](); // Clonage superficiel de Person
[Link] = (Address) [Link](); // Clonage profond de Address
return cloned;
}
public String getName() {
return name;
}
public Address getAddress() {
return address;
}
}
public class Main {
public static void main(String[] args) {
Address address = new Address("Paris");
Person original = new Person("Alice", address);

try {
// Clonage de l'objet avec clonage profond
Person clone = (Person) [Link]();

// Affichage des informations


[Link]("Original Address: " + [Link]().getCity()); // Paris
[Link]("Clone Address: " + [Link]().getCity()); // Paris

// Modification de l'adresse du clone


[Link]().setCity("Lyon");

// Affichage après modification


[Link]("After modification:");
[Link]("Original Address: " + [Link]().getCity()); // Paris (inchangé)
[Link]("Clone Address: " + [Link]().getCity()); // Lyon (modifié)

} catch (CloneNotSupportedException e) {
[Link]();
}
}
}
Design Pattern Prototype
public interface DocumentPrototype {
DocumentPrototype cloneDocument();
}

public class Document implements DocumentPrototype {


private String type;
private String contenu;

public Document(String type, String contenu) {


[Link] = type;
[Link] = contenu;
}

@Override
public DocumentPrototype cloneDocument() {
return new Document([Link], [Link]);
}

@Override
public String toString() {
return "Document{" +
"type='" + type + '\'' +
", contenu='" + contenu + '\'' +
'}';
}
}
import [Link];
import [Link];

// Classe DossierInscription avec Singleton + Prototype


public class DossierInscription implements Cloneable {
private List<DocumentPrototype> documents;

// Instance unique de DossierInscription (Singleton)


private static DossierInscription instance;

// Constructeur privé pour empêcher l'instanciation directe


private DossierInscription() {
[Link] = new ArrayList<>();
}

// Méthode pour obtenir l'unique instance (Singleton)


public static DossierInscription getInstance() {
if (instance == null) {
instance = new DossierInscription();
}
return instance;
}
// Ajouter un document au prototype
public void ajouterDocument(DocumentPrototype document) {
[Link](document);
}
// Clonage profond du dossier
@Override
public DossierInscription clone() {
DossierInscription dossierClone = null;
try {
// Créer un clone du dossier lui-même
dossierClone = (DossierInscription) [Link]();
[Link] = new ArrayList<>();
// Clonage en profondeur des documents
for (DocumentPrototype doc : [Link]) {
[Link]([Link]());
}
} catch (CloneNotSupportedException e) {
[Link]();
}
return dossierClone;
}
// Affichage des documents
public void afficherDocuments() {
for (DocumentPrototype document : documents) {
[Link](document);
}
}

// Réinitialiser l'instance pour réutilisation dans les tests


public static void resetInstance() {
instance = null;
}
}
DossierInscription dossierPrototype = [Link]();
// Ajouter des documents au prototype
Document certificatPrototype = new Document("Certificat", "Certificat par défaut");
Document assurancePrototype = new Document("Assurance", "Assurance par défaut");
[Link](certificatPrototype);
[Link](assurancePrototype);
// Cloner le prototype pour un étudiant
DossierInscription dossierEtudiant1 = [Link]();
((Document) [Link](0)).setContenu("Certificat de John Doe");
((Document) [Link](1)).setContenu("Assurance de John Doe");

// Cloner pour un autre étudiant


DossierInscription dossierEtudiant2 = [Link]();
((Document) [Link](0)).setContenu("Certificat de Jane Doe");
((Document) [Link](1)).setContenu("Assurance de Jane Doe");

// Afficher les dossiers clonés


[Link]("Dossier de l'étudiant 1:");
[Link]();

[Link]("\nDossier de l'étudiant 2:");


[Link]();

// Réinitialisation de l'instance singleton pour les tests ultérieurs (facultatif)


[Link]();
}
}
Design Patterns

Observer

Mohamed El yaakoubi
Catégories de Design Patterns
Observer
• Le pattern Observateur (en anglais Observer) définit une relation entre
objets de type un-à-plusieurs, de façon que, si un objet change d’état, tous
ceux qui en dépendent en soient informés et mis à jour automatiquement.
Observer Description

• On trouve des classes possédant des attributs dont les valeurs changent
régulièrement. De plus, un certain nombre de classes doit être tenu informé de
l’évolution de ces valeurs.

• Il n’est pas rare d’être confronté à ce problème notamment en développant une


classe métier et les classes d’affichages correspondantes.

• Le pattern Observer a pour objectif de construire une dépendance entre un sujet


et des observateurs de sorte que chaque modification du sujet soit notifiée aux
observateurs afin qu’ils puissent mettre à jour leur état.
Observer Description

• Un exemple que l’on rencontre souvent pour illustrer ce pattern est une
représentation entre une entreprise qui diffuse une magazine et des
personnes qui souhaitent s’y abonner (observateurs) et donc le recevoir
régulièrement.

• Le pattern observateur permet de lier de façon dynamique un observable à


des observateurs. Cette solution est faiblement couplée ce qui lui permet
d’évoluer facilement avec le modèle.
Modèle 1 : Diagramme de classes
Participants

• Observable est la classe abstraite qui représente tout objet qui notifie d’autres
objets des modifications de son état interne

• ObservableConcret est l’implémentation concrète de Observable qui gère des


états susceptible aux changements

• Observateur est l’interface de tout objet qui a besoin de recevoir des


notifications de changement d’état provenant des objets auprès desquels il s’est
préalablement inscrit

• ObservateurConcret est l’implémentation concrète de Observateur


Classe Observable

import [Link].*;

public abstract class Observable {


protected List<Observateur> observateurs = new ArrayList<Observateur>();

public void ajoute(Observateur observateur) {


[Link](observateur);
}

public void retire(Observateur observateur) {


[Link](observateur);
}

public void notifie() {


for (Observateur observateur : observateurs)
[Link]();
}
}
Classe Vehicule

public class Véhicule extends Oservable {


String description;
Double prix;
public String getDescription() {
return description;
}
public void setDescription(String description) {
[Link] = description;
notifie();
}
public Double getPrix() {
return prix;
}
public void setPrix(Double prix) {
[Link] = prix;
notifie();
}
}
Interface Observateur
public interface Observateur {
void actualise();
}

Classe VueVéhicule
public class VueVéhicule implements Observateur {
protected Véhicule véhicule;
protected String texte = "";
Public void setVehicule(Véhicule véhicule){
this.véhicule=véhicule;
}
public void actualise() {
texte = "Description "+vé[Link]()+" Prix : "+vé[Link]();
affiche();
}
public void affiche() {
[Link](texte);
}
}
Classe Utilisateur

public class Utilisateur {

public static void main(String[] args) {


Véhicule véhicule = new Véhicule();
VueVéhicule vue = new VueVéhicule();
[Link]éhicule(véhicule);
vé[Link](vue);
vé[Link]("Véhicule bon marché");
vé[Link](5000.0);
vé[Link](4500.0);
vé[Link](5500.0);
}
}
Modèle 2 : Diagramme de classes
Observable
import [Link].*;

public abstract class Observable {

protected List<Observateur> observateurs;

public void ajoute(Observateur observateur) {


[Link](observateur);
}

public void retire(Observateur observateur) {


[Link](observateur);
}

public void notifie() {


for (Observateur observateur : observateurs)
[Link](this);
}
}
Véhicule
import [Link];
public class Véhicule extends Observable {
String description;
Double prix;
public Véhicule(){
observateurs = new ArrayList<Observateur>();
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
[Link] = description;
notifie();
}
public Double getPrix() {
return prix;
}
public void setPrix(Double prix) {
[Link] = prix;
notifie();
}
}
Observateur
public interface Observateur {
void actualise(Observable o);
}

VueVéhicule public class VueVéhicule implements Observateur {

protected String texte = "";


public void actualise(Observable o) {
if(o instanceof Véhicule)
{
Véhicule v = (Véhicule)o;
texte = "Description "+ [Link]()+" Prix : "+ [Link]();
affiche();
}
}
public void affiche() {
[Link](texte);
}
}
Utilisateur

public class Utilisateur {

public static void main(String[] args) {

Véhicule véhicule = new Véhicule();


VueVéhicule vueVéhicule = new VueVéhicule();
vé[Link](vueVéhicule);
vé[Link]("Véhicule bon marché");
vé[Link](4500.0);
vé[Link](5000.0);
vé[Link](5500.0);
}
}
Implémentation d’une solution basée sur l’API Java
import [Link];
public class Vehicule extends Observable {
String description;
Vehicule Double prix;
public void notifierObservateurs()
{
setChanged(); // Méthode de l'API.
notifyObservers(); // Méthode de l'API.
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
[Link] = description;
notifierObservateurs();
}
public Double getPrix() {
return prix;
}
public void setPrix(Double prix) {
[Link] = prix;
notifierObservateurs();
}
}
import [Link];
import [Link];
VueVehicule public class VueVehicule implements Observer {
private String Desc;
@Override
public void update(Observable o, Object arg1) {
if(o instanceof Vehicule)
{
Vehicule v = (Vehicule) o;
Desc = "Description "+ [Link]()+" Prix : "+ [Link]();
affiche();
}
public void affiche(){
[Link](Desc);
}
}
Main public class Main {

public static void main(String[] args){


Vehicule v = new Vehicule();
VueVehicule w = new VueVehicule();
[Link](w);
[Link]("Description v1");
[Link](1000.00);
[Link]("Description v2");
[Link](2000.00);
}
}
Design Pattern Stat
(Etat)

35
Description

Le pattern State permet à un objet d’adapter son comportement en fonction de


son état interne.

Domaines d’application

Le pattern est utilisé dans le cas suivant :


• le comportement d’un objet dépend de son état ;
• l’implantation de cette dépendance à l’état par des instructions
conditionnelles est trop complexe.

36
Exemple

• Nous nous intéressons aux commandes d’un ensemble de produits.


• Elles sont décrites par une classe Commande.
• Les instances de cette classe possèdent un cycle de vie qui est illustré par un
diagramme d’états transitions

37
• L’état EnCours est l’état où la commande est en cours de constitution : le
client ajoute des produits.
• L’état Validée est l’état où la commande a été validée et réglée par le
client.
• Enfin l’état Livrée est l’état où les produits ont été livrés.
38
• La classe Commande possède des méthodes dont le comportement
diffère en fonction de son état.
• Par exemple :
• la méthode ajouteProduit n’ajoute des produits que si la
commande se trouve dans l’état EnCours.
• La méthode efface n’a pas de comportement dans l’état
Livrée.

39
• L’approche traditionnelle pour résoudre ces différences de
comportement consiste à utiliser des conditions dans le corps des
méthodes.
• Cette approche conduit souvent à des méthodes complexes à écrire et à
appréhender.

• Le pattern State propose une solution qui consiste à transformer chaque état
en une classe.
• Cette classe introduit les méthodes de la classe Commande dépendant des
états en leur conférant le comportement propre à cet état.

40
41
• la structure générique du pattern.

42
Les participants au pattern sont les suivants :

• MachineÉtat (Commande) est une classe concrète décrivant des objets qui sont des
machines à états, c’est-à-dire qui possèdent un ensemble d’états pouvant être
décrit par un diagramme d’états transitions. Cette classe maintient une référence
vers une instance d’une sous classe d’État qui définit l’état courant ;

• État (ÉtatCommande) est une classe abstraite qui introduit la signature des
méthodes liées à l’état et qui gère l’association avec la machine à états ;

• ÉtatConcretA et ÉtatConcretB (CommandeEnCours, CommandeValidée et


CommandeLivrée) sont des sous classes concrètes qui implantent le comportement
des méthodes relativement à chaque état.

43

Vous aimerez peut-être aussi