Académique Documents
Professionnel Documents
Culture Documents
Par N. Chenfour
Introduction
Singleton Client
- Singleton()
+ getInstance()
Singleton s ;
s = Singleton.getInstance() ;
return instance ;
private Singleton() {
}
public Client() {
useSingleton();
}
Solution Java :
C’est une classe concrète qui implémente l’interface
Cloneable.
Elle hérite de la méthode clone() définie « protected » dans la
classe Object.
Redéfinir « public » la méthode clone().
Client p Prototype
ConcretePrototype1 ConcretePrototype2
Prototype p2 = p.clone()
+ clone() : Prototype + clone() : Prototype
package dp.creational.prototype;
public CP2() {
name = "";
}
// getters & setters
// ...
public Client() {
creation1();
}
void creation1() {
CP1 p1 = new CP1(20, 30);
Prototype q1 = new CP2("Prototype");
CP1 p2 = p1.clone();
Prototype q2 = q1.clone();
void creation2() {
Prototype tp1[] = {
new CP1(20, 30),
new CP2("Prototype")
};
Prototype tp2[] = new Prototype[tp1.length];
Creator Product
+ anOperation()
+ abstract createProduct() : Product
…
createProduct() ;
… ConcreteProduct1 ConcreteProduct2
ConcreteCreator1 ConcreteCreator2
+ createProduct() + createProduct()
public Client() {
ConcreteCreator1 cc1 = new ConcreteCreator1();
creation(cc1);
Exemple :
Realisation d’un panneau :
- de Boutons
- de cases à cocher
- de boutons radio
Î Les classes suivantes :
AbstractButtonPanel : AbstractCreator
ButtonPanel : ConcreteCreator1
CheckBoxPanel : ConcreteCreator2
RadioButtonPanel : ConcreteCreator3
Client : Client
AbstractButton : Product
JButton : ConcreteProduct1
JCheckBox : ConcreteProduct2
JRadioButton : ConcreteProduct3
void exp01() {
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
p.add(new ButtonPanel(new String[]{"Choix 1","Choix 2",
"Choix 3"}));
p.add(new RadioButtonPanel(new String[]{"Choix 1",
"Choix 2","Choix 3"}));
p.add(new CheckBoxPanel(new String[]{"Choix 1","Choix 2",
"Choix 3"}));
setContentPane(p);
pack();
setVisible(true);
}
void exp02() {
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
AbstractButtonPanel abp[] = {
new ButtonPanel(new String[]{"Choix 1","Choix 2",
"Choix 3"}),
new RadioButtonPanel(new String[]{"Choix 1",
"Choix 2","Choix 3"}),
new CheckBoxPanel(new String[]{"Choix 1","Choix 2",
"Choix 3"})
};
for (int i=0; i<abp.length; i++) p.add(abp[i]);
abp[1].add("Choix 4");
changeLayout(abp[1]);
setContentPane(p);
pack();
setVisible(true);
}
void build() {
objet1 = fabrique.getObject1() ;
objet2 = fabrique.getObject2() ;
objet3 = fabrique.getObject3() ;
...
}
}
Class client {
public static void main(String args[]) {
//choix de la factory
AbstractFactory f = new ConcreteFactory1();
Client
creation() factory
AbstractFactory “interface”
AbstractObject1
+ getObject1() : AbstractObject1
+ getObject2() : AbstractObject2
+ getObject3() : AbstractObject2
Object1A Object1B
ConcreteFactory1 ConcreteFactory2
+ getObject1() + getObject1() AbstractObject2
+ getObject2() + getObject2()
+ getObject3() + getObject3()
Object2A Object2B
Collection A Collection B
Pour que le client puisse utiliser ces classes indifféremment et donc fournir
le même code d’accès quelque soit l’objet de classe à utiliser, il suffit de
créer un adaptateur par classe fournissant le même service de la classe
adaptée mais avec le même nom de méthode (même interface d’accès).
Remarque :
Il existe 2 implémentations possibles de ce DP. :
Adaptateur de classe (Class Adapter) :
Dans ce cas la relation entre l’adaptateur et la classe à adapter est
une relation d’héritage.
Adaptee2
+ specificRequest2()
Adapter2 specificRequest2() ;
+ request()
Adaptee1
+ specificRequest1()
for (Target t : targets) { Adapter1
t.request(); a1
} + request()
a1.specificRequest1() ;
Adaptee2
+ specificRequest2()
Adapter2
a2
+ request()
a2.specificRequest2() ;
public class A {
public void trier() {
}
}
public class B {
public void sortById() {
}
}
public class C {
public void sortByName() {
}
}
void sortA() {
A a = new A();
a.trier();
}
void sortB() {
B b = new B();
b.sortById();
}
void sortC() {
C c = new C();
c.sortByName();
}
}
Exemples Java :
1. La séparation : AbstractButton Æ ActionListener Î plusieurs
ActionListeners peuvent être envisagé et ainsi associés à
différents types de boutons
Client
operation()
imp.service() ;
Exemple à Implémenter :
- un Parseur XML,
- un Système de connexion Base de données,
- un Ficher Excel,
- un fichier texte formaté en colonnes,
- etc.
L’opération proposée par les GOF dans les classes de ce Design Pattern
peut être comme exemple, une opération d’affichage (explorer) : pour
explorer un arbre il suffit d’afficher l’info du nœud et d’explorer
(récursivement) les nœuds fils.
Component
operation()
add(Component)
remove(int) *
get(int)
size()
Leaf Composite
operation() operation()
children
add(Component)
remove(int)
get(int) for (Component c : children) {
size() c.operation() ;
}
Component 1
ConcreteComponent Decorator
component
ConcreteDecorator1 ConcreteDecorator2
Exemple 1 :
LabeledTextField (zone de texte étiquetée), BorderedTextField (zone de
texte avec bordure) et BorderedLabeledTextField (zone de texte étiquetée
et avec bordure) : classiquement, il s’agit de 3 classes différentes. Mais
avec ce Design Pattern, on sépare le décorateur Î Labeled, Bordered :
seulement 2 classes + la flexibilité d’appliquer Labeled à Bordered ou
Bordered à Labeled (sans créer une nouvelle classe)
Exemple 2 :
C’est l’un des Design Patterns les Plus utilisés et les plus simples à mettre
en œuvre (basé uniquement sur l’agrégation). Il s’agit d’encapsuler un
ensemble d’objets de classes variées dans une même classe appelée
façade permettant de simplifier l’accès (généralement complexe) aux
différentes classes.
Client
Composant1
service1()
Composant2
Façade
service2()
service()
Composant3
service3()
Exemples :
- Une classe Database encapsulant : Class, Connexion,
DatabaseMetaData, Resultset, etc…
- Une classe Form encapsulant des JLabel, JTextField, etc..
Client
FlyweightFactory Flyweight
getFlyweight(key) operation(state)
Flyweight1 Flyweight2
operation(state) operation(state)
Exemple :
- Un bouton « Exit » avec son comportement (L’ActionListener
permettant de fermer la fenêtre).
- Un bouton « OK », mais le comportement (ou l’étiquette)
constitue la propriété extrinsèque sous forme d’un
ActionListener (ou setText(…) ).
Exemples :
1- une méthode getName(…) qui retourne dans le RealObject un String
pouvant être nul Î getName().equals(…) peut se terminer en erreur. A
corriger par un Proxy retournant le cas échéant une chaîne vide.
Subject « interface »
+ request()
…
RO.request() ;
…
Client Handler
+handleRequest() successor
ConcreteHandler1 ConcreteHandler2
+handleRequest() +handleRequest()
Invoker Command
+setCommand() +execute()
receiver.action();
Client
Context
Client
AbstractExpression
interpret(Context)
TerminalExpression NonTerminalExpression
interpret(Context) interpret(Context)
Exemple :
Client
+ createIterator()
Aggregate Iterator
+ first()
+ createIterator() + next()
+ isDone()
+ currentItem()
ConcreteAggregate ConcreteIterator
Collection Iterator
+ iterator() + next()
+ hasNext()
+ remove()
LinkedList ListIterator
+ iterator() + previous()
+ listIterator() + hasPrevious()
+ add(…)
+ set(…)
+ nextIndex()
+ previousIndex()
Mediator Colleague
ConcreteMediator
ConcreteColleague ConcreteColleague
public Mediator() {
}
Originator Memento
- state - state
+ setMemento(Memento m) + setState(state)
+ createMemento() + getState()
caretaker
state = m.getState();
Caretaker
+ addMemento(Memento, Index)
Memento m = new Memento(state); + getMemento(Index)
careTaker.addMemento(m, index);
Client
operation()
Observer
Subject
observers + update(Subject s)
+ attach(Observer)
+ detach(Observer)
- notify()
for (Observer o : observers) {
o.update(this) ;
}
ConcreteSubject
ConcreteObserver
- state
- observerState
+ setState(state)
+ update(Subject s)
+ getState()
Context State
+ setState(State) state + handle()
+ request()
state.handle() ;
ConcreteState1 ConcreteState2
+ handle() + handle()
Remarque :
Thread
+ run()
state.run() ;
ReadState WriteState
+ run() + run()
Context Strategy
+ setStrategy(Strategy) strategy + algorithm()
+ request()
…
strategy.algorithm();
… Strategy1 Strategy2
+ algorithm() + algorithm()
Exemple :
+ Algorithmes de tri.
+ Un Parseur XML
Remarque :
Ce design pattern ressemble au design pattern State dans sa structure
mais avec la différence suivante :
AbstractClass
+ templateMethod()
+ primitiveOperation1() …
+ primitiveOperation2() primitiveOperation1() ;
…
primitiveOperation2()
…
ConcreteClass1 ConcreteClass2
+ primitiveOperation1() + primitiveOperation1()
+ primitiveOperation2() + primitiveOperation2()
Client
operation() Element
accept(Visitor)
Visitor
visitCE1(ConcreteElement1)
visitCE2(ConcreteElement2) ConcreteElement1 ConcreteElement2
accept(Visitor) accept(Visitor)
service1() service2()
ConcreteVisitor1 ConcreteVisitor2
visitCE1(ConcreteElement1) visitCE1(ConcreteElement1)
visitCE2(ConcreteElement2) visitCE2(ConcreteElement2) v.visitCE2(this) ;
v.visitCE1(this) ;
Remarques :
1. Ce design pattern permet d’éviter de polluer des classes avec
une multitude de services variés et qui change d’une classe à
une autre.