Design Pattern en Java

 

Design pattern

Design Patterns is a modern classic in the literature of object-oriented development, offering timeless and elegant solutions to common problems in software design. It describes patterns for managing object creation, composing objects into larger structures, and coordinating control flow between objects. The book provides numerous examples where using composition rather than inheritance can improve the reusability and flexibility of code. Note, though, that it’s not a tutorial but a catalog that you can use to find an object-oriented design pattern that’s appropriate for the needs of your particular application–a selection for virtuoso programmers who appreciate (or require) consistent, well-engineered object-oriented designs. Design Patterns is a modern classic in the literature of object-oriented development, offering timeless and elegant solutions to common problems in software design. It describes patterns for managing object creation, composing objects into larger structures, and coordinating control flow between objects. The book provides numerous examples where using composition rather than inheritance can improve the reusability and flexibility of code. Note, though, that it’s not a tutorial but a catalog that you can use to find an object-oriented design pattern that’s appropriate for the needs of your particular application–a selection for virtuoso programmers who appreciate (or require) consistent, well-engineered object-oriented designs.

So now let’s dive what’s under the hood of the design pattern in this article I try to explain and give some sample diagramm and snipset code example .

Book reference

Design Patterns: Elements of Reusable Object-Oriented Software

 

Pattern Facade

Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.

Frequency of use: high

 

* Objectif de ce design Pattern :

a pour but de regrouper les interfaces d’un ensemble d’objets en une interface unifiée rendant cet ensemble simple à utiliser . En gros cela veut dire que nous exposons à nos client une interface permettant d’accéder à un ensemble de service sous jacent

Exemple :
Nous pouvons imaginer un système client Server, dans lequel le serveur expose un ensemble de service via une interface (la facade) que le client s’attacchera d’attaquer via RMI (remote method invocation) / corba  …
Cette manière de faire permet de facilité le développement d’applications distribuées en masquant au client la complexité situé coté serveur (traitement lourds , EJb transactionnel … )

UML class diagram

 

 

 

=> Code source

package facade;

import java.util.List;

public class ClientWebservice {
	public static void main(String[] args) {
		WebServiceAuto webserviceAuto = new WebServiceAutoImpl();
		System.out.println(webserviceAuto.document(0));
		System.out.println(webserviceAuto.document(1));

		List<String> resultats =  webserviceAuto.chercheVehicules(6000, 1000);
		if(resultats.size() >0 ){
			System.out.println("véhicule est comprix entre 5000 et 7000");
			for (String resultat : resultats) {
				System.out.println("  "+resultat);
			}
		}
	}
}

package facade;

import java.util.List;

public interface WebServiceAuto {
	String document(int index);
	List<String> chercheVehicules(int prixMoyen ,int ecartMax);
}

package facade;

import java.util.List;

public class WebServiceAutoImpl implements WebServiceAuto{

	Catalogue catalogue = new ComposantCatalogue();
	GestionDocument gestionDocument = new ComposantGestionDocument();
	public String document(int index) {
		return gestionDocument.document(index);
	}
	public List<String> chercheVehicules(int prixMoyen, int ecartMax) {
		return catalogue.retrouveVehicules(prixMoyen, ecartMax);
	}
}

package facade;

public interface GestionDocument {
	String document (int index ) ;
}
package facade;

public class ComposantGestionDocument implements GestionDocument {
	public String document(int index) {
		return "Document numéro "+index ;
	}

}
package facade;

import java.util.List;

public interface Catalogue {
	List<String> retrouveVehicules(int prixMin,int prixMax);
}

package facade;

import java.util.ArrayList;
import java.util.List;

public class ComposantCatalogue implements Catalogue {
	Object [] descriptionVehicule ={
			"Berline 5 portes ", 6000,
			"Compact 3 portes " , 4000,
			"Espace 5 portes",8000,
			"Break 5 portes ",7000,
			"Coupé 2 portes ",9000,"Utilitaire 3 portes ",5000
	};

	/**
	 * Partie métier sattachant a retourver les listes de vehicules entre 2 ecarts de prix
	 */
	public List<String> retrouveVehicules(int prixMin, int prixMax) {
		int index , taille ;
		List<String> resultat = new ArrayList<String>();
		taille = descriptionVehicule.length/2;

		for (int i = 0; i < taille; i++) {
			int prix = ((Integer)descriptionVehicule[2*i+1]).intValue();
			if((prix >= prixMin ) && (prix <= prixMax)){
				resultat.add((String) descriptionVehicule[2*i]);
			}
		}
		return resultat;
	}

}

Pattern Observer

 

package observer;

public class Program {

	public static void main(String[] args) {
		FluxRss flux1= new FluxRss();
		flux1.setDescription("Android latest news ");
		flux1.setModele("Android"); 

		IObservateur ob = new FluxObservateur(flux1);
		ob.informe();
	}
}

package observer;

import java.util.ArrayList;
import java.util.List;

public abstract class Sujet {
	List<IObservateur> obs = new ArrayList<>();
	void ajoute (IObservateur o){
		obs.add(o);
	}
	void  retire(IObservateur o ){
		obs.remove(o);
	}
	public void notifie (){
		for (IObservateur element : obs) {
			element.update();
		}
	}
}

package observer;

public class FluxRss extends Sujet {
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public String getModele() {
		return modele;
	}
	public void setModele(String modele) {
		this.modele = modele;
	}
	String description;
	String modele; 

}

public interface IObservateur {
	String update ();
	void informe();
}

public class FluxObservateur implements IObservateur{
	private FluxRss fluxRss;
	String texte = "";
	public FluxObservateur(FluxRss fluxRss) {
		this.fluxRss = fluxRss;
		fluxRss.ajoute(this);
	}

	@Override
	public String update() {
		texte = "Description Feed: "+fluxRss.getDescription()+" \nName: "+fluxRss.getModele();
		return texte ;
	}
	public void informe(){
		System.out.println(update());
	}
}

Abstract Factory

Ce pattern permet de regrouper la création des objets en familles sans que l’on est à savoir comment les classes concrètes sont crées .

Dans cet exemple de diagramme de classe la classe dites cliente catalogue recurpère l’objet dit « fabriquer » ( AutomobileEssence , automobileElectrique )

Souvent on utilise aussi le pattern Builder plus simple à implémenter

diagramme de classe Abstract Factory

diagramme de classe Abstract Factory

public class Catalogue {
public static int nbAutos = 3 ;

public static void main(String[] args) {
Scanner reader = new Scanner(System.in);

FabriqueVehicule fabrique = null ;
Automobile[] autos = new Automobile[nbAutos];
System.out.println("Vehicule essence (1) ou essence (2)");
String choix = reader.next();
if(choix.equals("1")){
fabrique = new FabriqueVehiculeEssence();
}

if(choix.equals("2")){
fabrique = new FabriqueVehiculeElectrique();
}

for (int i=0;i<nbAutos;i++) {
autos[i] = fabrique.creeAutomobile("standard", "pink",2, 2.666);
}
for (Automobile automobile : autos) {
automobile.afficheCaracteristique();
}

}

package abstractfactory;

public interface FabriqueVehicule {
	Automobile creeAutomobile(String modele,String couleur,int puissance,double espace);
}
package abstractfactory;

public class FabriqueVehiculeElectrique implements FabriqueVehicule{

	public Automobile creeAutomobile(String modele, String couleur,
			int puissance, double espace) {
		return new AutomobileElectrique(modele, couleur, puissance, espace);
	}

}
package abstractfactory;

public class FabriqueVehiculeEssence implements FabriqueVehicule{

	public Automobile creeAutomobile(String modele, String couleur,
			int puissance, double espace) {
		return new AutomobileEssence(modele, couleur, puissance, espace);
	}

}

package abstractfactory;

public abstract class Automobile {
	String modele ;
	String couleur ;
	int puissance ;
	double espace ;

	public Automobile(String modele,String couleur,int puissance, double espace ){
		this.modele=modele;
		this.couleur=couleur;
		this.puissance= puissance ;
		this.espace=espace ;
	}

	public abstract void afficheCaracteristique();
}
public class AutomobileElectrique extends Automobile{

	public AutomobileElectrique(String modele, String couleur, int puissance,
			double espace) {
		super(modele, couleur, puissance, espace);
	}
	public void afficheCaracteristique() {
		System.out.println("Automobile electrique \n"+
		"couleur "+couleur+" puissance: "+puissance+" espace  :"+espace );
	}
}

public class AutomobileEssence extends Automobile{
	public AutomobileEssence(String modele, String couleur, int puissance,
			double espace) {
		super(modele, couleur, puissance, espace);
	}
	public void afficheCaracteristique() {
		System.out.println("Automobile electrique \n"+
				"couleur "+couleur+" puissance: "+puissance+" espace  :"+espace );
	}
}

Pattern Builder

definition

Separate the construction of a complex object from its representation so that the same construction process can create different representations. 

Frequency of use: medium low

Builder Structure

public class BuilderExample {
	public static void main(String[] args) {
		Cook cook = new Cook();  //director
		PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();//concretebuilder
		PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();

		cook.setPizzaBuilder(hawaiianPizzaBuilder);
		cook.constructPizza();

		Pizza hawaiian = cook.getPizza();

		cook.setPizzaBuilder(spicyPizzaBuilder);
		cook.constructPizza();

		Pizza spicy = cook.getPizza();
	}

}
public class Cook {
	/**
	 * @uml.property  name="pizzaBuilder"
	 * @uml.associationEnd
	 */
	private PizzaBuilder pizzaBuilder;

	/**
	 * @param pb
	 * @uml.property  name="pizzaBuilder"
	 */
	public void setPizzaBuilder(PizzaBuilder pb) {
		pizzaBuilder = pb;
	}

	public Pizza getPizza() {
		return pizzaBuilder.getPizza();
	}

	public void constructPizza() {
		pizzaBuilder.createNewPizzaProduct();
		pizzaBuilder.buildDough();
		pizzaBuilder.buildSauce();
		pizzaBuilder.buildTopping();
	}

}
abstract class PizzaBuilder {
	/**
	 * @uml.property  name="pizza"
	 * @uml.associationEnd
	 */
	protected Pizza pizza;

	/**
	 * @return
	 * @uml.property  name="pizza"
	 */
	public Pizza getPizza() {
		return pizza;
	}

	public void createNewPizzaProduct() {
		pizza = new Pizza();
	}

	public abstract void buildDough();

	public abstract void buildSauce();

	public abstract void buildTopping();
}

public class HawaiianPizzaBuilder  extends PizzaBuilder {
	public void buildDough() {
		pizza.setDough("cross");
	}

	public void buildSauce() {
		pizza.setSauce("mild");
	}

	public void buildTopping() {
		pizza.setTopping("ham+pineapple");
	}

}

class SpicyPizzaBuilder extends PizzaBuilder {
	public void buildDough() {
		pizza.setDough("pan baked");
	}

	public void buildSauce() {
		pizza.setSauce("hot");
	}

	public void buildTopping() {
		pizza.setTopping("pepperoni+salami");
	}
}

public class Pizza {
	/**
	 * @uml.property  name="dough"
	 */
	private String dough = "";
	/**
	 * @uml.property  name="sauce"
	 */
	private String sauce = "";
	/**
	 * @uml.property  name="topping"
	 */
	private String topping = "";
	/**
	 * @return
	 * @uml.property  name="dough"
	 */
	public String getDough() {
		return dough;
	}
	/**
	 * @param dough
	 * @uml.property  name="dough"
	 */
	public void setDough(String dough) {
		this.dough = dough;
	}
	/**
	 * @return
	 * @uml.property  name="sauce"
	 */
	public String getSauce() {
		return sauce;
	}
	/**
	 * @param sauce
	 * @uml.property  name="sauce"
	 */
	public void setSauce(String sauce) {
		this.sauce = sauce;
	}
	/**
	 * @return
	 * @uml.property  name="topping"
	 */
	public String getTopping() {
		return topping;
	}
	/**
	 * @param topping
	 * @uml.property  name="topping"
	 */
	public void setTopping(String topping) {
		this.topping = topping;
	}

}

Diagramme de classe prototype

Protype Pattern

package prototype;

public abstract class Cookie implements Cloneable{
	public Cookie clone() throws CloneNotSupportedException{
		Cookie copy = (Cookie)super.clone();
		return copy;
	}

	abstract void prototypeFactory(int x) ;
	abstract	void printValue() ;
}

package prototype;

/**
 * @author  artaud
 */
public class CookieMachineClient {
	/**
	 * @uml.property  name="cookie"
	 * @uml.associationEnd
	 */
	private Cookie cookie; // could have been a private Cloneable cookie;

	public CookieMachineClient(Cookie cookie){
		this.cookie = cookie;
	}
	public Cookie makeCookie() throws CloneNotSupportedException{
		return cookie.clone();
	}

	public static void main(String[] args) {
		try {
			Cookie cookie= null;
			CoconutCookie mycookie= new CoconutCookie(100);
			CookieMachineClient vCookieMachineClient = new CookieMachineClient(mycookie);

			for(int i =0;i<10;i++){
				cookie =  vCookieMachineClient.makeCookie(); //clone our objectg
				cookie.prototypeFactory(i*100);//verify that our clone object is really there
				cookie.printValue();
			}
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}
package prototype;

/**
 *
 * @author artaud
 *
 */
public class CoconutCookie extends Cookie{
	int x ; 

	public CoconutCookie(int x ) {
		this.x=x;
	}
	@Override
	void printValue() {
		System.out.println("Value : "+x);
	}

	@Override
	void prototypeFactory(int x) {
		this.x=x ;
	}

}

Decorator Pattern

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Frequency of use: medium

Exemple développé ici .
pattern decorator
package decorator;
public class LauchCoffeeOrder {
	public static void main(String[] args) {
		Coffee coffee = new SimpleCoffee();
		System.out.println("Cost : "+  coffee.getCost()+" Ingredients : "+ coffee.getIngredients());

		coffee  = new ColdCofee(coffee);
		System.out.println("Cost : "+  coffee.getCost()+" Ingredients : "+ coffee.getIngredients());

		coffee  = new LatteCoffee(coffee);
		System.out.println("Cost : "+  coffee.getCost()+" Ingredients : "+ coffee.getIngredients());
	}
}

package decorator;
public interface  Coffee {
	public int REGULAR_PRICE = 10;
	public int getCost();
	public String getIngredients();
}

package decorator;

public class SimpleCoffee implements Coffee{
	@Override
	public int getCost() {
		return REGULAR_PRICE;
	}

	@Override
	public String getIngredients() {
		return "Coffee ";
	}
}
package decorator;

public abstract class CoffeeDecorator implements Coffee{
	/**
	 * @uml.property  name="coffee"
	 * @uml.associationEnd
	 */
	private Coffee coffee;
	public final  String SEPARATOR = ", ";
	public CoffeeDecorator(Coffee coffee) {
		this.coffee = coffee ;
	}

	public int getCost() {
		return coffee.getCost();
	}

	public String getIngredients() {
		return coffee.getIngredients();
	}

}

package decorator;

public class ColdCofee extends CoffeeDecorator{

	public ColdCofee(Coffee coffee) {
		super(coffee);
	}
	public int getCost(){
		return super.getCost() + 5;
	}
	public String getIngredients(){
		return super.getIngredients()+ SEPARATOR + " Ice ";
	}
}
package decorator;

public class LatteCoffee extends CoffeeDecorator{
	public LatteCoffee(Coffee coffee) {
		super(coffee);
	}
	public int getCost(){
		return 	super.getCost() + 10;
	}

	public String getIngredients(){
		return super.getIngredients()+ SEPARATOR  + " Milk ";
	}
}

visitor Pattern

Composite Pattern

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

Frequency of use: medium high

 

UML class diagram

 

exemple développé ici

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

package composite;

public class LaunchComputation {
	public static void main(String[] args) {
		PointComponent curve = new Point(1, 2050,10 );
		PointComponent curve2 = new Point(1, 2010,10 );
		PointComponent curve3 = new Point(1, 3010,10 );

		ScenarioComponent scenarioHighRisk = new ScenarioHighVolatility();
		scenarioHighRisk.add(curve);
		scenarioHighRisk.add(curve2);
		scenarioHighRisk.add(curve3);
		scenarioHighRisk.operation();

	PointComponent curve4 = new Point(1, 210,10 );
		PointComponent curve5 = new Point(1, 2010,10 );
		PointComponent curve6 = new Point(1, 3010,10 );

		ScenarioComponent scenarioLowRisk = new ScenarioLowVolatility();
		scenarioLowRisk.add(curve4);
		scenarioLowRisk.add(curve5);
		scenarioLowRisk.add(curve6);
		scenarioLowRisk.operation();
	}
}

package composite;

public interface PointComponent {
	public void operation();
	public float getDay();
	public float getPrice();
	public void setPrice(float price);
	public int getSensibility();
}

package composite;

public class Point implements PointComponent{

	float  day; // abcisse
	float  price;//ordonnée
	int sensibility; //sensibility pricing variation  

	Point (float day,float price,int sensibility){
		this.day=day;
		this.price = price ;
		this.sensibility = sensibility;
	}

	/**
	 * @return the day
	 */
	public float getDay() {
		return day;
	}
	/**
	 * @param day the day to set
	 */
	public void setDay(float day) {
		this.day = day;
	}
	/**
	 * @return the price
	 */
	public float getPrice() {
		return price;
	}
	/**
	 * @param price the price to set
	 */
	public void setPrice(float price) {
		this.price = price;
	}
	/**
	 * @return the sensibility
	 */
	public int getSensibility() {
		return sensibility;
	}
	/**
	 * @param sensibility the sensibility to set
	 */
	public void setSensibility(int sensibility) {
		this.sensibility = sensibility;
	}

	@Override
	public void operation() {
	}
}

package composite;

import java.util.ArrayList;
import java.util.List;

public abstract class ScenarioComponent implements PointComponent{
	private PointComponent curveScenario ;
	List<PointComponent> points = new ArrayList<PointComponent>();

	ScenarioComponent(){}

	public List<PointComponent>add(PointComponent point){
		points.add(point);
		return points;
	}

	public List<PointComponent>remove(PointComponent point){
		points.remove(point);
		return points;
	}
	public List<PointComponent> getChilds(){
		return this.points;
	}

	public void operation(){
		curveScenario.operation();
	}

	public float getDay(){
		return curveScenario.getDay();
	}

	public float getPrice(){
		return curveScenario.getPrice();
	}
	public void setPrice(float price){
		curveScenario.setPrice(price);
	}
	public int getSensibility(){
		return curveScenario.getSensibility();
	}
	/**
	 * @uml.property  name="pointComponent"
	 * @uml.associationEnd  inverse="scenarioComponent:composite.PointComponent"
	 */
	private PointComponent pointComponent;

	/**
	 * Getter of the property <tt>pointComponent</tt>
	 * @return  Returns the pointComponent.
	 * @uml.property  name="pointComponent"
	 */
	public PointComponent getPointComponent() {
		return pointComponent;
	}

	/**
	 * Setter of the property <tt>pointComponent</tt>
	 * @param pointComponent  The pointComponent to set.
	 * @uml.property  name="pointComponent"
	 */
	public void setPointComponent(PointComponent pointComponent) {
		this.pointComponent = pointComponent;
	}
}

package composite;

public class ScenarioHighVolatility  extends ScenarioComponent{

	public ScenarioHighVolatility(){};

	public void operation(){
		System.out.println("\n**** High Volatility scenario *****");
		for (PointComponent point : points) {
			float scenarioPrice = point.getPrice() - point.getSensibility()-20;
			point.setPrice(scenarioPrice);
			System.out.println("Price : " + point.getPrice());
		}
	}
}

package composite;

public class ScenarioLowVolatility extends ScenarioComponent{

	public ScenarioLowVolatility(){};

	public void operation(){
		System.out.println("**** Low Volatility scenario *****");
		for (PointComponent point : points) {
			float scenarioPrice = point.getPrice() - point.getSensibility()- 5;
			point.setPrice(scenarioPrice);
			System.out.println("Price : " + point.getPrice());
		}
	}
}

Observator Pattern

  • Le pattern observer permet d’avoir des objets faiblement couplés.
  • Ce pattern est basé sur une relation : de un à plusieurs.
  • Au lieu de coupler nos objets directement, on préfère coupler les interfaces qu’ils implémentent.
  • Grâce à ce pattern, nos objets restent indépendants les uns des autres !

Très utiliser dans les systèmes de facturation(ajout client, traitement auxiliaire) ou dans les interfaces UI comme le Swing

 

Where is the controller in this example?? The controllers are the
instances of the anonymous classes which handle the button
presses.

package observer;

import java.awt.Button;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class CounterGui extends Frame {
	// The counter. (The model!)
	private int counter = 0;
	// The view.
	private TextField tf = new TextField(10);
	public CounterGui(String title) {
		super(title);
		Panel tfPanel = new Panel();
		tf.setText("0");
		tfPanel.add(tf);
		add("North", tfPanel);
		Panel buttonPanel = new Panel();
		Button incButton = new Button("Increment");
		incButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				counter++;
				tf.setText(counter + "");
			}
		} );
		buttonPanel.add(incButton);
		Button decButton = new Button("Decrement");
		decButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				counter--;
				tf.setText(counter + "");
			}
		} );
		buttonPanel.add(decButton);
		Button exitButton = new Button("Exit");
		exitButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		} );
		buttonPanel.add(exitButton);
		add("South", buttonPanel);
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		} );
	}
	public static void main(String[] argv) {
		CounterGui cg = new CounterGui("CounterGui");
		cg.setSize(300, 100);
		cg.setVisible(true);
	}
}

Visitor

The benefit of this pattern is that if the logic of operation changes, then we need to make change only in the visitor implementation rather than doing it in all the item classes.

Another benefit is that adding a new item to the system is easy, it will require change only in visitor interface and implementation and existing item classes will not be affected.

The drawback of visitor pattern is that we should know the return type of visit() methods at the time of designing otherwise we will have to change the interface and all of its implementations. Another drawback is that if there are too many implementations of visitor interface, it makes it hard to extend.

An advance way to use this pattern is to couple it with Chain responsability http://www.tutorialspoint.com/design_pattern/chain_of_responsibility_pattern.htm

package visitor.model;

import visitor.IMessageInVisitor;
import visitor.ItemElement;

public class MessageIn implements ItemElement{
	String id;
	double price ;
	double positions;
	public MessageIn(String id , double price , double positions) {
		this.id= id;
		this.price = price;
		this.positions = positions ;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public double getPositions() {
		return positions;
	}
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("MessageIn [id=");
		builder.append(id);
		builder.append(", price=");
		builder.append(price);
		builder.append(", positions=");
		builder.append(positions);
		builder.append("]");
		return builder.toString();
	}
	public void setPositions(double positions) {
		this.positions = positions;
	}
	@Override
	public TradeXmlOutput accept(IMessageInVisitor visitor) {
		return visitor.visit(this);
	}
}
package visitor.model;

public class TradeXmlOutput {
	public String reference ;
	public String getReference() {
		return reference;
	}
	public void setReference(String reference) {
		this.reference = reference;
	}
	public double getPrice() {
		return price;
	}
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("TradeXmlOutput [reference=");
		builder.append(reference);
		builder.append(", price=");
		builder.append(price);
		builder.append("]");
		return builder.toString();
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public double price ; 

}
package visitor;

import java.util.ArrayList;

import visitor.model.MessageIn;

public class Client {
	public static void main(String[] args) {
		MessageIn message = new MessageIn("TPX15784", new Double("200"), new Double(100));
		IMessageInVisitor visitor = new MessageInVisitorImpl();
		ArrayList<MessageIn> messages = new ArrayList<MessageIn>();
		messages.add(message);
		for (ItemElement e : messages) {
			System.out.println(e.accept(visitor).toString());
		}
	}
}
package visitor;

import visitor.model.MessageIn;
import visitor.model.TradeXmlOutput;

public interface IMessageInVisitor {
	public TradeXmlOutput visit(MessageIn message);
}
package visitor;

import visitor.model.TradeXmlOutput;

public interface ItemElement {
	public TradeXmlOutput accept(IMessageInVisitor visitor);
}
package visitor;

import visitor.model.MessageIn;
import visitor.model.TradeXmlOutput;

public class MessageInVisitorImpl implements IMessageInVisitor{
	@Override
	public TradeXmlOutput visit(MessageIn message) {
		TradeXmlOutput e = new TradeXmlOutput();
		//Map our element
		e.reference =  message.getId();
		e.price = message.getPrice()*2;
		return e;
	}
}

seconde version decoupling treatment .
package visitor;

import java.util.ArrayList;

import visitor.model.MessageIn;

public class Client {
	public static void main(String[] args) {
		//Mock data In
		MessageIn message = new MessageIn("TPX15784", new Double("200"), new Double(100));		

		IMessageInVisitor visitor = new MessageInReferenceVisitorImpl();

		ArrayList<MessageIn> messages = new ArrayList<MessageIn>();
		messages.add(message);
		for (ItemElement e : messages) {
			visitor.setOutput(e.accept(visitor));
			visitor = new MessageInPriceVisitorImpl() ;
			visitor.setOutput(e.accept(visitor));
		}
		//print RESULT
		System.out.println(visitor.getOutput().toString());
	}
}
package visitor;

import visitor.model.MessageIn;
import visitor.model.TradeXmlOutput;

public class MessageInPriceVisitorImpl extends IMessageInVisitor{
	@Override
	public TradeXmlOutput visit(MessageIn message) {
		TradeXmlOutput e = getOutput();
		e.price = message.getPrice()*2;
		return e;
	}
}
package visitor;

import visitor.model.MessageIn;
import visitor.model.TradeXmlOutput;

public class MessageInReferenceVisitorImpl extends  IMessageInVisitor{
	@Override
	public TradeXmlOutput visit(MessageIn message) {
		//Map our element
		TradeXmlOutput e = getOutput();
		e.reference =  message.getId();
		return e;
	}
}
package visitor;

import visitor.model.MessageIn;
import visitor.model.TradeXmlOutput;

public abstract class IMessageInVisitor {
	TradeXmlOutput output;
	public abstract TradeXmlOutput visit(MessageIn message);
	public TradeXmlOutput getOutput() {
		if (output ==null){
			return new TradeXmlOutput();
		}
		return output;
	}
	public void setOutput(TradeXmlOutput output) {
		this.output = output;
	}
}

Singleton Pattern

  • Permet de n’avoir q’une instance du POJO java .
public class Singleton {
        private static Singleton instance = null;
        private Singleton() {}
        public static synchronized Singleton getInstance() {
			if (instance == null) {
					instance = new Singleton();
			}
			return instance;
        }
}

annexe

http://userpages.umbc.edu/~tarr/dp/lectures/Observer.pdf

http://www.dofactory.com/Patterns/Patterns.aspx

http://www.javaworld.com/javaworld/javatips/jw-javatip29.html

http://www.croes.org/gerald/blog/observateurs-observables-vs-publish-subscribe/51/

Exemple in .NET

http://www.dofactory.com/Patterns/Patterns.aspx

Livre

Gamma, Helm, Johnson, Vlissides, »Design Patterns, » Addison-Wesley, 1994, ISBN 0-201-63361-2