designpattern

  • Provide an interface for creating families of related or dependent objects without specifying their concrete classes.



    Source Code

    /**
     * Abstract factory declares an interface for operations that create abstract
     * product objects.
     * 
     * @role __Factory
     */
    public interface AbstractFactory {
            /**
      * Creates abstract product
      */
            ProductA createProductA();        /**
      * Creates abstract product
      */
            ProductB createProductB();}
    
    /**
     * Abstract factory declares an interface for operations that create abstract
     * product objects.
     * 
     * @role __Factory
     */
    public interface AbstractFactory {
            /**
      * Creates abstract product
      */
            ProductA createProductA();        /**
      * Creates abstract product
      */
            ProductB createProductB();}
    
    /**
     * Abstract product - an interface for a type of Product object.
     * 
     * @role __Product
     * @see AbstractFactory
     */
    public interface ProductA {
    
            /*
      * add product method declarations here
      */
    }
    
    /**
     * Concrete Factory implements operations of AbstractFactory to create Concrete
     * product objects.
     */
    public class MyFactory implements AbstractFactory {
    
            /**
      * Creates concrete product ConcreteProduct1
      */
            public ProductA createProductA() {
                    return new ConcreteProduct1();        }
    
            /**
      * Creates concrete product ConcreteProduct2
      */
            public ProductB createProductB() {
                    return new ConcreteProduct2();        }
    
    }
    
    /**
     * Concrete product defines a product object to be created by the corresponding
     * concrete factory.
     * 
     * @see MyFactory
     */
    public class ConcreteProduct1 implements ProductA {
    
    }
    
    /**
     * Concrete product defines a product object to be created by the corresponding
     * concrete factory.
     * 
     * @see MyFactory
     */
    public class ConcreteProduct2 implements ProductB {
    
    }
    
  • Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.



    Source Code

    /**
     * Defines an existing interface that needs adapting
     * 
     * @role __Adaptee
     */
    public class Adaptee {
    	/* Some adaptee-specific behavior */
    	public void specificRequest() {
    		// some adaptee specific stuff is going here
    	}
    }
    
    /**
     * This class adapts the interface of Adaptee to the Target interface
     */
    
    public class Adapter extends Target {
    	/** reference to the object being adapted */
    	private Adaptee adaptee;
    
    	/**
    	 * @param adaptMe
    	 *            class to adapt whis this adapter
    	 */
    	public Adapter(Adaptee adaptMe) {
    		this.adaptee = adaptMe;
    	}
    
    	/**
    	 * Implementation of target method that uses adaptee to perform task
    	 */
    	public void request() {
    		adaptee.specificRequest();
    	}
    
    }
    
    /**
     * This class defines domain-specific interface used by client
     * 
     * @role __Target
     */
    
    public abstract class Target {
    	/** This method is called by client when he needs some domain-specific stuff */
    	public abstract void request();
    }
    
  • Decouple an abstraction from its implementation so that the two can vary independently.

    from the gang of the four





    Source Code

    /**
     * Defines Abstraction interface. Stores reference to implementation.
     * 
     * @role __Abstraction
     */
    public abstract class Abstraction {
    	/** Reference to actual implementation */
    	private Implementor impl;
    
    	/**
    	 * @return implementation-in-action.
    	 */
    	protected Implementor getImplementor() {
    		return impl;
    	}
    
    	/**
    	 * This sample operation delegates call to particular implementation
    	 */
    	public void someOperation() {
    		getImplementor().someOperationImpl();
    	}
    }
    
    /**
     * Concrete implementation
     */
    
    public class ConcreteImplementorA extends Implementor {
    	/** @see patterns.gof.bridge.ImplementorsomeOperationImpl() */
    	public void someOperationImpl() {
    		// provide implementation here
    	}
    }
    
    /**
     * Concrete implementation
     */
    
    public class ConcreteImplementorB extends Implementor {
    	/** @see patterns.gof.bridge.ImplementorsomeOperationImpl() */
    	public void someOperationImpl() {
    		// provide implementation here
    	}
    }
    
    /**
     * Defines interface for implementation classes. Is not oblidged to provide
     * one-to-one correspondence to interface of Abstraction.
     * 
     * @role __Implementor
     */
    
    public abstract class Implementor {
    	/** Implement this method to provide implementation-specific behavior */
    	public abstract void someOperationImpl();
    }
    
  • Separate the construction of a complex object from its representation so that the same construction process can create different representations.



    Source Code

    /**
     * The interface Product defines interface to create parts of the
     * Product.
     */
    public interface Builder {
    
        /**
         * Construct part of the complex Product.
         */
        public void buildPart();
    
        /**
         * Construct the Product.
         *
         * @return the constructed product
         */
        public Product getProduct();
    }
    
    /**
     * The ConcreteBuilder is the product of a concrete builder.
     *
     */
    public class ConcreteBuilder implements Product {
    }
    
    
    /**
     * The ConcreteBuilderBuilder creates and assembles parts of
     * the Product.
     *
     */
    public class ConcreteBuilderBuilder implements Builder {
    
        /**
         * Reference to Product being constructed
         */
        private ConcreteBuilder concreteBuilder;
    
        /**
         * Construct part of the complex Product.
         */
        public void buildPart() {
            // put your code here
        }
    
        /**
         * Construct the Product.
         *
         * @return the constructed product
         */
        public Product getProduct() {
            return concreteBuilder;
        }
    }
    
    
    /**
     * The ConcreteBuilderClient initialized the Director with a
     * Concrete Bulder to create the Product and gets result from the Builder.
     *
     */
    public class ConcreteBuilderClient {
    
        /**
         * Use the Builder to create the Product.
         */
        public void createProduct() {
            ConcreteBuilderBuilder builder = new ConcreteBuilderBuilder();
            new Director(builder).construct();
            Product product = builder.getProduct();
        }
    }
    
    
    /**
    * The class Director manages Product creation using Builder.
    */
    public class Director {
    
        /**
         * Reference to Builder currently used
         */
        private Builder builder;
    
        /**
         * Create a new Director instance.
         *
         * @param builder the builder which will create the product
         */
        public Director(Builder builder) {
            this.builder = builder;
        }
    
        /**
         * Construct the Product using the Builder.
         */
        public void construct() {
            builder.buildPart();
        }
    }
    
    
    /**
     * The interface Product defines a complex object that is
     * constructed part-by-part with Builder.
    
     */
    public interface Product {
    }
    
    
    
    
    
    
    
  • Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.



    Source code

    /**
     * Handles request it is responsible to.
     */
    public class ConcreteHandler extends Handler {
            /**
      * Handle request or delegate it.
      */
            public void handleRequest() {
                    boolean canProcessThisRequest = false;                if (canProcessThisRequest) {
                            // handle request if possible
                    } else {
                            // pass it to the next in chain
                            super.handleRequest();                }
            }
    
    }
    
    /**
     * Defines interface for request handling
     * @role __Handler
     */
    public class Handler {
            private Handler successor;        /** Default request handling */
            public void handleRequest() {
                    if (successor != null) {
                            successor.handleRequest();                }
            }
    
            public Handler getSuccessor() {
                    return this.successor;        }
    
            public void setSuccessor(Handler successor) {
                    this.successor = successor;        }
    
    }
    
    
    
    
    
  • Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. Builds an undo/redo manager and a set of  command classes.



    Source Code

    /**
     * Declares an interface for executing an operation
     * @role __Command
     */
    public interface Command {
            /** this method is called by client to execute this command */
            void executeCommand();}
    
    /**
     * Defines a binding betweeen a Receiver object and an action. 
     * Implements Command by invoking the corresponding operation(s) on Receiver
     */
    public class CommandA implements Command {
            public CommandA() {
                    // put command initialization code here
            }
    
            /** @see patterns.gof.command.CommandexecuteCommand()*/
            public void executeCommand() {                 // provide implementation here
            }
    }
    
    /**
     * Defines a binding betweeen a Receiver object and an action. 
     * Implements Command by invoking the corresponding operation(s) on Receiver
     */
    public class CommandB implements Command {
            public CommandB() {
                    // put command initialization code here
            }
    
            /** @see patterns.gof.command.CommandexecuteCommand()*/
            public void executeCommand() {                 // provide implementation here
            }
    }
    
    /**
     * Concrete Command that executes a sequence of Commands.
     */
    public class MacroCommand implements Command {
            /** Commands to execute */
            private Command[] commands;        /** @param commands Commands to execute */
            public MacroCommand(Command[] commands) {
                    this.commands = commands;        }
    
            /** Executes sequence of Commands */
            public void executeCommand() {
                    if (commands != null) {
                            for (int i = 0; i < commands.length; i++) {
                                    commands[i].executeCommand();                        }
                    }
            }
    
    }
    
    
  • Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.



    Source Code

    /**
     * Defines the interface for objects that can have responsibilities added to the
     * dynamically.
     * 
     * @role __Component
     */
    public abstract class Component {
    	/**
    	 * Sample operation.
    	 */
    	public abstract void doSomeStuff();
    }
    
    /**
     * Defines an object to which additional responsibilities can be attached.
     */
    
    public class ConcreteComponent extends Component {
    	/** @see patterns.gof.decorator.ComponentdoSomeStuff() */
    	public void doSomeStuff() {
    		// provide implementation here
    	}
    }
    
    /**
     * Adds responsibilities to the component.
     */
    
    public class ConcreteDecorator extends Decorator {
    	public ConcreteDecorator(Component decorateMe) {
    		super(decorateMe);
    	}
    
    	/**
    	 * Behavior added by decorator.
    	 */
    	private void addedBehavior() {
    		// some extra functionality goes here
    	}
    
    	public void doSomeStuff() {
    		super.doSomeStuff();
    		addedBehavior();
    	}
    }
    
    /**
     * Maintains the reference to a Component object and defines an interface that
     * conforms to Component's interface
     * 
     * @role __Decorator
     */
    
    public abstract class Decorator extends Component {
    	/** reference to the decorated component */
    	protected Component component;
    
    	/**
    	 * @param decorateMe
    	 *            component to decorate
    	 */
    	public Decorator(Component decorateMe) {
    		this.component = decorateMe;
    	}
    
    	public void doSomeStuff() {
    		component.doSomeStuff();
    	}
    }
    
  • This package contains a dynamic polymorphic factory...

    •  New class can be add dynamically to the factory... even during runtime (dynamic)
    • Factory methods are in a separate class as virtual functions. (polymorphism)
    • Different types of factories can be subclassed from the basic factory.. (abstract)
    • Useful iin case of licence problem, since Concrete classes are created at runtime, and only need to reside in classpath (If they are not present the code still compile). Below, the example show multiple authorization and autorisation scheme, that can be switche on/off very fast.
    • Factory can be driven with an external condition (properties, registry....)
     
    Notice also that the specific concrete classes are dynamically loaded on demand...(class.forname())


    Source Code

    /**
     * Creation date: (7/19/2002 2:50:45 PM)
     * 
     * @author: Cedric Walter
     */
    public interface AuthentificationIF {
    
            public boolean Authentificate(HttpServletRequest req,                        HttpServletResponse resp);        public boolean hasAutorisation(HttpServletRequest req,                        HttpServletResponse resp);}
    
    public abstract class AuthentificationA implements AuthentificationIF {
    
    /**
      * AuthentificationA constructor comment.
      */
            public AuthentificationA() {
                    super();        }
    
           
    /**
      * Authentificate method comment.
      */
           
    public abstract boolean Authentificate(                       
    javax.servlet.http.HttpServletRequest req,                       
    javax.servlet.http.HttpServletResponse resp);
    }
    
    abstract class AuthentificationFactoryA {
    
            private static java.util.Map factories = new java.util.HashMap();       
    /**
      * ComputeFactory constructor comment.
      */
            public AuthentificationFactoryA() {
                    super();        }
    
            public static void addFactory(String id, AuthentificationFactoryA f) {
                    factories.put(id, f);        }
    
            public static final AuthentificationIF createAuthentification(String id)                        
    throws FactoryCreationException { if (!factories.containsKey(id)) { try { // Load dynamically Class.forName(id);
    }
    catch (ClassNotFoundException e) { throw new FactoryCreationException(id);
    } // verify that it has been stored if (!factories.containsKey(id))
    throw new FactoryCreationException(id);
    } return ((AuthentificationFactoryA) factories.get(id)).getAuthentification();
    } protected abstract AuthentificationIF getAuthentification();} /** * concrete class of the abstract factory */ public class MyAuthentificationFactory extends AuthentificationFactoryA { public MyAuthentificationFactory() { super(); } /** * not use since it is subclass */ protected AuthentificationIF getAuthentification() { return null; } } /** * @author: Cedric Walter */ public class NimiusAuthentification extends AuthentificationA implements AuthentificationIF { private static class Factory extends AuthentificationFactoryA { protected AuthentificationIF getAuthentification() { return new NimiusAuthentification(); } } static { AuthentificationFactoryA.addFactory("com.waltercedric.gof.pattern.factory.NimiusAuthentification", new NimiusAuthentification.Factory()); }
    /**
      * Local constructor comment.
      */
            public NimiusAuthentification() {
                    super();        }
    
           
    /**
      * Authenficate method comment.
      */
            public boolean Authentificate(javax.servlet.http.HttpServletRequest req, 
    javax.servlet.http.HttpServletResponse resp)
    { //do some stuff return true; } public boolean hasAutorisation(javax.servlet.http.HttpServletRequest req,
    javax.servlet.http.HttpServletResponse resp)
    { //do some stuff return true; } } /** * @author: Cedric Walter */ public class NoAuthentification extends AuthentificationA implements AuthentificationIF { private static class Factory extends AuthentificationFactoryA { protected AuthentificationIF getAuthentification() { return new NoAuthentification(); } } static { AuthentificationFactoryA.addFactory( "com.waltercedric.gof.pattern.factory.NoAuthentification", new NoAuthentification.Factory()); } /** * Local constructor comment. */ public NoAuthentification() { super(); } /** * Authenficate method comment. */ public boolean Authentificate(javax.servlet.http.HttpServletRequest req,
    javax.servlet.http.HttpServletResponse resp) { return true; } /** * hasAutorisation method comment. */ public boolean hasAutorisation(javax.servlet.http.HttpServletRequest req,
    javax.servlet.http.HttpServletResponse resp) { return true; } } /** * @author: Cedric Walter */ public class ObtreeAuthentification extends AuthentificationA implements AuthentificationIF { private static class Factory extends AuthentificationFactoryA { protected AuthentificationIF getAuthentification() { return new ObtreeAuthentification(); } } static { AuthentificationFactoryA.addFactory( "com.waltercedric.gof.pattern.factory.ObtreeAuthentification", new ObtreeAuthentification.Factory()); } /** * Local constructor comment. */ public ObtreeAuthentification() { super(); } /** * Authenficate method comment. */ public boolean Authentificate(javax.servlet.http.HttpServletRequest req,
    javax.servlet.http.HttpServletResponse resp) { return true; } /** * hasAutorisation method comment. */ public boolean hasAutorisation(javax.servlet.http.HttpServletRequest req,
    javax.servlet.http.HttpServletResponse resp) { return true; } }
  • Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.



    Source Code

    /**
     * Knows which subsystem classes are responsible for a request.
     * Delegates client requests to appropiate susystem objects.
     * @role __Facade
     */
    public class Facade {
            /** reference to particular subsystem */
            private SubsystemA theSubsystemA;        /** reference to particular subsystem */
            private SubsystemB theSubsystemB;        /** this method is called by client */
            public void facadeMethod() {
                    // multiple subsystems could be involved
                    // to provide some functionality
            }
    }
    
    /**
     * Implements subsystem functionality. Handles work assigned by the Facade object.
     * Has no knowledge of the facade.
     * @role __System
     */
    public class SubsystemA {
            /** some functionality */
            public void subsystemFunctionality() {
            }
    }
    
    /**
     * Implements subsystem functionality. Handles work assigned by the Facade object.
     * Has no knowledge of the facade.
     * @role __System
     */
    public class SubsystemB {
            /** some functionality */
            public void subsystemFunctionality() {
            }
    }
  • Use sharing to support large numbers of fine-grained objects efficiently.




    Source Code

    /**
     * Declares an interface through which flyweights can receive and act on
     * extrinsic state.
     * 
     * @role __Flyweight
     */
    public interface Flyweight {
    	void sampleOperation(FlyweightContext context);
    }
    
    /**
     * Represents extrinsic state of flyweight(s).
     * 
     * @role __State
     */
    
    public interface FlyweightContext {
    }
    
    /**
     * Implements the Flyweight interface and adds storage for intrinsic state, if
     * any. Objects of this class must be sharable. Any state it stores must be
     * intrinsic (independent of this object's context)
     */
    
    public class ConcreteFlyweight implements Flyweight {
    	public ConcreteFlyweight(Object key) {
    		// initialize internal state
    	}
    
    	/** @see patterns.gof.flyweight.FlyweightsampleOperation(FlyweightContext) */
    	public void sampleOperation(FlyweightContext context) {
    		// provide implementation here
    	}
    }
    
    /**
     * Creates and manages flyweight objects. Ensures that flyweights are shared
     * properly. When a client requests a flyweight, this factory supplies an
     * existing instance or creates one, if none exists.
     * 
     * @role __Factory
     */
    
    public class FlyweightFactory {
    	private HashMap flyweight;
    
    	public FlyweightFactory() {
    		flyweight = new HashMap();
    	}
    
    	public Flyweight getFlyweight(Object key) {
    		if (flyweight.containsKey(key)) {
    			return (Flyweight) flyweight.get(key);
    		} else {
    			Flyweight newFlyweight = new ConcreteFlyweight(key);
    			flyweight.put(key, newFlyweight);
    			return newFlyweight;
    		}
    	}
    
    	/**
    	 * @return new instance ofunshared flyweight
    	 */
    	public Flyweight getUnsharedConcreteFlyweight() {
    		return new UnsharedConcreteFlyweight();
    	}
    }
    
    /**
     * Not all Flyweight subclasses need to be shared
     */
    
    public class UnsharedConcreteFlyweight implements Flyweight {
    	/** @see patterns.gof.flyweight.FlyweightsampleOperation(FlyweightContext) */
    	public void sampleOperation(FlyweightContext context) {
    		// provide implementation here
    	}
    
    }
    
  • Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.



    Source code

    /**
     * Declares an abstract Interpret operation that is common to all nodes in the
     * abstract syntax tree.
     * 
     * @role __InterpreterExpression
     */
    public abstract class AbstractExpression {
            public abstract void interpret(Context context);}
    
    /**
     * Builds an abstract syntax tree representing a particular sentence in the
     * language that the grammar defines. Invokes the Interpret operation.
     */
    public class Client {
            public AbstractExpression getExpression() {
                    // put your code to create expression here
                    return null;        }
    
            public void sampleOperation() {
                    Context context = new Context();                
    getExpression().interpret(context);
    } } /** * Contains information that is global to interpreter. * * @role __InterpreterContext */ public class Context { } /** * One such class is required for every rule in the grammar. */ public class NonterminalExpression extends AbstractExpression { public void interpret(Context context) { // put your code here } } /** * Implements an Interpret operation associated with terminal symbols in the * grammar. */ public class TerminalExpression extends AbstractExpression { public void interpret(Context context) { // put your code here } }
  • You do not create your objects but describe (using cofiguration file) how they should be created and wired together in code. A container (for ex: in case of Spring framework, the IOC container) is then responsible for hooking it all up.

    In a typical IOC scenario, the container creates all the objects, wires them together by setting the necessary properties, and determines when methods will be invoked. The three implementation pattern types for IOC are:

    Type 1 Services need to implement a dedicated interface through which they are provided with an object from which they can look up dependencies (for example, additional needed services).

    Type 2Dependencies are assigned through JavaBeans properties (for example, setter methods).

    Type 3 Dependencies are provided as constructor parameters and are not exposed as JavaBeans properties.


  • http://www.securitypatterns.org/index.html
  • Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.




    Source code

    /**
     * Each colleague knows its Mediator object. Communicates with its mediator
     * whenever it would have otherwise communicated with another colleague.
     * 
     * @role __Colleague
     */
    public abstract class Colleague {
            /** my mediator */
            private Mediator mediator;        /** Create colleague which knows about supplied mediator */
            protected Colleague(Mediator mediator) {
                    this.mediator = mediator;        }
    
            /** @return mediator this colleague knows about */
            public Mediator getMediator() {
                    return mediator;        }
    
    }
    
    /** Concrete Colleague */
    public class ConcreteColleagueA extends Colleague {
            public ConcreteColleagueA(Mediator mediator) {
                    super(mediator);        }
    
            public void sampleOperation() {
                    // some state changes occur,
                    // notify mediator about them
                    getMediator().changed(this);        }
    
    }
    
    /** Concrete Colleague */
    public class ConcreteColleagueB extends Colleague {
            public ConcreteColleagueB(Mediator mediator) {
                    super(mediator);        }
    
            public void sampleOperation() {
                    // some state changes occur,
                    // notify mediator about them
                    getMediator().changed(this);        }
    
    }
    
    /**
     * Implements cooperative behavior by coordinating Colleague objects. Knows and
     * maintains its colleagues.
     */
    public class ConcreteMediator implements Mediator {
            /** reference to concrete colleague */
            private ConcreteColleagueA aConcreteColleagueA;        /** reference to concrete colleague */
            private ConcreteColleagueB aConcreteColleagueB;        public void changed(Colleague colleague) {
                    // handle changes of particular colleague
            }
    
            public void setConcreteColleagueA(ConcreteColleagueA colleague) {
                    aConcreteColleagueA = colleague;        }
    
            public void setConcreteColleagueB(ConcreteColleagueB colleague) {
                    aConcreteColleagueB = colleague;        }
    
    }
    
    /**
     * Defines an interface for communicating with Colleague objects.
     * 
     * @role __Mediator
     */
    public interface Mediator {
            /** Colleagues calls this method to notify Mediator that something changed */
            void changed(Colleague colleague);}
    
    
  • Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.




    Source code

    /**
     * Creates a memento containing a snapshot of its current internal state.
     * Uses the memento to restore its internal state.
     * @role __Originator
     */
    public class Originator {
            public Memento createMemento() {
                    return new ConcreteMemento(this);        }
    
            public void setMemento(Memento memento) {
                    if (memento instanceof ConcreteMemento) {
                            // extract state from memento
                    }
            }
    
    }
    
    /**
     * Represents narrow interface of the memento visible to Caretaker
     * @role __Memento
     */
    public interface Memento {
    }
    
    /**
     * Stores internal state of the Originator object. 
     * This is sort of wide memento interface,
     * visible to Originator.
     */
    public class ConcreteMemento implements Memento {
            public ConcreteMemento(Originator originator) {
                    // initialize memento with originator's state
            }
    
    }
    
    
  • Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.



    Source code

    /**
     * Knows its observers. Any number of Observer objects
     * may observe a subject. Provides an interface for attaching
     * and detaching Observer objects.
     * @role __Subject
     */
    public class Subject {
            private ArrayList observers = new ArrayList();        public void attach(Observer observer) {
                    observers.add(observer);        }
    
            public void detach(Observer observer) {
                    int idx = observers.indexOf(observer);                if (idx != -1) {
                            observers.remove(idx);                }
            }
    
            protected void notifyObservers() {
                    Iterator it = observers.iterator();                while (it.hasNext()) {
                            ((Observer) it.next()).update(this);                }
            }
    
    }
    
    /**
     * Defines an updating interface for objects that
     * should be notified of changes in a subject.
     * @role __Observer
     */
    public interface Observer {
            /**
      * Update method.
      */
            public void update(Subject subject);}
    
    /**
     * Stores state of interest to ConcreteObserver objects.
     * Sends a notification to its observers when its state changes.
     */
    public class ConcreteSubject extends Subject {
    
            // add your subject's specific stuff here
    }
    
    /**
     * Implements the Observer updating interface to keep 
     * its state consistent with the subject's.
     */
    public class ConcreteObserver implements Observer {
            public void update(Subject subject) {
                    // put your code here
            }
    
    }
    
    
    
  • Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.



    Source Code

    /**
     * Declares interface for cloning itself.
     * @role __Prototype
     */
    public interface Prototype {
            Prototype createCopy();}
    
    /**
     * Implements an operation for cloning itself.
     */
    public class ConcretePrototype1 implements Prototype {
            protected ConcretePrototype1(ConcretePrototype1 prototype) 
            {
               // initialize new copy with prototype
            }
    
            public Prototype createCopy() {
               return new ConcretePrototype1(this);        
            }
    }
    
    /**
     * Implements an operation for cloning itself.
     */
    public class ConcretePrototype1 implements Prototype {
            protected ConcretePrototype1(ConcretePrototype1 prototype) {
              // initialize new copy with prototype
            }
    
            public Prototype createCopy() {
                    return new ConcretePrototype1(this);        
            }
    }
    
  • Provide a surrogate or placeholder for another object to control access to it. Options are provided to implement all interfaces of the subject class as well as all of the public methods of the subject class



    Source Code

    /**
     * Represents a proxy for Subject
     */
    public class Proxy extends Subject {
    	/**
    	 * Holds the subject instance.
    	 */
    	private Subject subject;
    
    	/** @see patterns.gof.proxy.SubjectsampleMethod() */
    	public int sampleMethod() {
    		return subject.sampleMethod();
    	}
    }
    
    /**
     * Represents a real subject
     */
    
    public class RealSubject extends Subject {
    	public int sampleMethod() {
    		/* something happens here */
    		return 0;
    	}
    }
    
    /**
     * Represents a subject
     * 
     * @role __Subject
     */
    
    public abstract class Subject {
    	/**
    	 * This is sample method to be called by proxy
    	 */
    	public abstract int sampleMethod();
    }
    
  • Ensure a class only has one instance, and provide a global point of access to it.

    Statically Initialized
    The singleton class is implemented by defining a static field that is statically initialized (that is, the field is initialized when the class is initialized). This has the advantage that invocations of the method used to access the singleton do not incur the overhead of checking whether or not the instance has been created.

    Dynamically Initialized
    The singleton class is implemented by defining a static field that is dynamically initialized (that is, the field is initialized the first time its value is requested). This has the advantage that the singleton is not allocated unless it is needed, potentially reducing memory usage.



    Links

    Source Code

    /**
     * Represents a singleton.
     */
    public class Singleton {
    	/**
    	 * Holds the singleton instance.
    	 */
    	private static Singleton instance;
    
    	/**
    	 * constructor must be private to avoid automatic creation of default
    	 * constructor by the compiler
    	 *  
    	 */
    	private Singleton() {
    		super();
    	}
    
    	/**
    	 * Returns the singleton instance.
    	 * 
    	 * synchronized to prevent race problem
    	 * 
    	 * @return the singleton instance
    	 */
    	public static synchronized Singleton getInstance() {
    		if (instance == null) {
    			instance = new Singleton();
    		}
    		return instance;
    	}
    }
    
    Singleto
  • Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.




    Source Code

    /**
     * Defines an interface for encapsulating the behavior associated with a
     * particular state of the Context.
     * 
     * @role __State
     */
    public interface State {
            void handle(String sample);}
    
    /**
     * Defines an interface of interest to clients. Maintains an instance of a
     * ConcreteState subclass that defines the current state.
     */
    public class Context {
            private State state;        public void setState(State newState) {
                    this.state = newState;        }
    
            public void someOperation() {
                    state.handle("aaa");        }
    
    }
    
    /**
     * Implements a behavior associated with a state of the Context.
     */
    public class ConcreteState implements State {
            public void handle(String sample) {
                    /* put your code for this particular state here */
            }
    
    }
    
    /pre>
  • Defines the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses refine certain steps of an algorithm without changing the algorithm's structure.


    Source Code


    /**  
    * This class defines abstract primitive operations that concrete
    * subclasses define to implement steps of an algorithm. Implements a template
    * method defining the skeleton of an algorithm.
    *
    * @role __TemplateContext */ public abstract class Context { /**
    * Primitive operation.
    */ public abstract void doPrimitiveOperation(); /**
    * Defines the skeleton of an algorithm. Calls primitive operations as well
    * as operations defined in AbstractClass or those in other objects.
    */ public void templateMethod() { // put your code here doPrimitiveOperation(); // put your code here } } /**
    * Implements the primitive operations to carry out subclass-specific steps of
    * the algorithm.
    */ public class ConcreteClass extends Context { /**
    @see patterns.gof.templatemethod.ContextdoPrimitiveOperation()
    */ public void doPrimitiveOperation() { // provide implementation here } }
    Template 
  • Create a class that approximates an equivalent Pascal enumeration or C enum. A specific enumeration will be represented by a class with specific instances corresponding to each element of the enumerations and public static final fields to access the instances.
    • Existing in Java Tiger 1.5

    • Elements are ordered and comparable
    • Enumeration elements are serializable
    • Enumeration element Name lookup is supported
    • Methods sequencing is included



    Source Code

    /**
     * Type Safe Enumeration: Colors elements: Red, Blue, Green, Yellow, White
     */
    public final class Colors implements Comparable, Serializable {
    	/**
    	 * The map of enumeration elements to names.
    	 */
    	private static HashMap nameLookup = new HashMap(5);
    
    	/**
    	 * The array of enumeration elements.
    	 */
    	private static Colors[] ordinalLookup = new Colors[5];
    
    	/**
    	 * The "Red" enumeration element
    	 */
    	public static final Colors Red = new Colors("Red", 0);
    
    	/**
    	 * The "Blue" enumeration element
    	 */
    	public static final Colors Blue = new Colors("Blue", 1);
    
    	/**
    	 * The "Green" enumeration element
    	 */
    	public static final Colors Green = new Colors("Green", 2);
    
    	/**
    	 * The "Yellow" enumeration element
    	 */
    	public static final Colors Yellow = new Colors("Yellow", 3);
    
    	/**
    	 * The "White" enumeration element
    	 */
    	public static final Colors White = new Colors("White", 4);
    
    	/**
    	 * The string representation of the enumeration.
    	 */
    	private final String printName;
    
    	/**
    	 * The ordinal value of the enumeration used for comparison purposes.
    	 */
    	private final int ordinal;
    
    	/**
    	 * Create an enumeration element. Prevent instances of this class from being
    	 * created externally.
    	 * 
    	 * @param name
    	 *            the name of the enumeration element
    	 * @param position
    	 *            the ordinal position of the enumeration element
    	 */
    	private Colors(String name, int position) {
    		this.ordinal = position;
    		this.printName = name;
    		ordinalLookup[position] = this;
    		nameLookup.put(name, this);
    	}
    
    	/**
    	 * Compare two enumeration elements
    	 * 
    	 * @param arg
    	 *            the object to compare this to
    	 * @return the difference between the ordinal values
    	 * @see java.lang.ComparablecompareTo(Object)
    	 */
    	public int compareTo(Object arg) {
    		return this.ordinal - ((Colors) arg).ordinal;
    	}
    
    	/**
    	 * Return the string representation of the enumeration.
    	 * 
    	 * @return the name of the enumeration element
    	 */
    	public String toString() {
    		return printName;
    	}
    
    	/**
    	 * Resolve the enumeration element.
    	 * 
    	 * @return the resolved enumeration element
    	 * @throws ObjectStreamException
    	 *             if the enumeration element could not be resolved.
    	 */
    	private Object readResolve() throws ObjectStreamException {
    		return ordinalLookup[ordinal];
    	}
    
    	/**
    	 * Return the first enumeration element
    	 * 
    	 * @return the first enumeration element
    	 */
    	public static Colors first() {
    		return ordinalLookup[0];
    	}
    
    	/**
    	 * Return the last enumeration element
    	 * 
    	 * @return the last enumeration element
    	 */
    	public static Colors last() {
    		return ordinalLookup[ordinalLookup.length - 1];
    	}
    
    	/**
    	 * Return the enumeration element preceding this element
    	 * 
    	 * @return the enumeration element preceding this element
    	 */
    	public Colors predecessor() {
    		return (this == first()) ? null : ordinalLookup[ordinal - 1];
    	}
    
    	/**
    	 * Return the enumeration element following this element
    	 * 
    	 * @return the enumeration element following this element
    	 */
    	public Colors successor() {
    		return (this == last()) ? null : ordinalLookup[ordinal + 1];
    	}
    
    	/**
    	 * Return the enumeration element with the given name
    	 * 
    	 * @param name
    	 *            the name of the enumeration element to find
    	 * @return the named enumeration element
    	 */
    	public static Colors valueOf(String name) {
    		return (Colors) nameLookup.get(name);
    	}
    
    }
    
  • Beaucoup de personne me connaissant et qui m'écrivent me demande comment je developpe mes programmes java car je trouve toujours le moyen d'en faire des frameworks...ce qui est par définition plus dur.

    Eh bien j'applique plusieurs petite règles simples...

    1. Un bon tool: je ne travaille qu'avec eclipse (www.eclipse.org) car c'est un IDE de qualité et malgré la quantité de perspectives (j'en ai 16), views (j'en ai 64) et plugins (>20), je m'y sens à   l'aise. Je privilégie la vue hiérarchique "java browsing view" avec une vue supplementaire "hiérarchie" (F4) car cela facilite la navigation et le découpage sémantique losque je dévelope (projets<-> packages<->objets<->hiérarchie<->méthodes<->code)
    2. Un environnement de travail propice: Je travaille avec 2 écrans (un 21'' et un 15'4 LCD) car rien n'est plus ennuyeux de perdre son temps à   bouger/réduire/changer de tâches sans cesse. Cela me permet aussi de travailler en parallèle. C'est déroutant au début mais rien n'est plus malléable que le cerveau humain et vous vous surprendrez au bout de quelques semaines en passant d'un écran à   l'autre sans cesse. C'est simple si demain je trouve une méthode fiables et peu couteuse en temps CPU (pas avec une carte video USB svp) pour avoir un troisième écran, je saute sur l'occasion immédiatement.

    Ces 2 règles ne participent qu'a hauteur de 15% à   un travail de qualité...mais elle réduisent le stress au poste de travail. Le reste est plus standard...

    Quelques techniques de développement modernes, ont bouleversés ma vie (relativement courte) de developpeur:

    1. Les "design patterns" pour appliquer des élements d'architectures éprouvés à   des classes de problèmes.
      Il faut bien sur les comprendre (quand les appliquer et leurs bénéfices/inconvénients) sans pour autant savoir les implémenter. J'en place un maximum sans effort grà ¢ce à   un générateur de pattern (plugin eclipse).
      Je me débrouille pour avoir des hièrarchies la ou c'est évident (mais en général, elles apparaissent toute seule cf. Refactoring), j'ai rarement des super classes non abstraites et sans interface, je crée toujours des interfaces pour augmenter le niveau d'abstraction dans mon code à   chaque niveau (layer) et laisser à   l'utilisateur le droit d'insérer son code dans le mien.
      Rappeler vous: sans interfaces, vous n'avez pas de polymorphisme en java et un typage trop fort (pourquoi encore passer des types concrets à   vos objets alors que l'on peut jouer à   des niveaux plus abstraits avec les interfaces?)
      Les design patterns apportent, à   mon code, la flexibilité (pattern de créations), le dynamisme (pattern de comportements) ou améliore le design (pattern de structures)
      Je n'hésite pas non plus à   créer des objets en quantités et à   leur donner les droits et fonctions minimums qui leurs incombent, car peu m'inporte les pertes de performances: je privilégie le design quitte à   devoir profiler plus tard.
    2. Les "antipatterns" (www.antipatterns.com/) leur contraire, en général lorsque je récupère du code dans un mauvais état. Cela m'aide à   trouver quelle "design patterns" peut arranger la situation (en vue de la correction d'un bug, pour améliorer la maintenance etc...) 
    3. Je programme de plus en plus "par intentions" (lien-> informit), une idée centrale de l'extreme programming (XP voir  www.extremeprogramming.org ). Comment le client voudrait avoir à   utiliser mon code, en fait à   quoi doit ressembler idéalement le code (le nom des types, des méthodes, des mediateurs). Je les écrits (comme un squelette) et bien sur ils n'existent pas encore, (donc compile error). Je force donc eclipse à   les créer (Quick fix ou CTRL-1)  et remplis les blancs, à   savoir l'implémentation, ce qui est forcément une tache moins intéressante.

    4. l'UML (Unified Modelling Language) oui de plus en plus, mais uniquement pour observer l'évolution des dépendances entre les objects (les motifs et les relations) sur mon 2ème écran. Et toujours en reverse engineering: je modifie le code java et observe d'un oeil le diagramme UML. En fait cela rejoint la programmation par intention dans un sens sauf que normalement on part de l'UML par intention pour créer le squellete du code java et non l'inverse. Le sens que j'utilise permet cependant de compléter mon javadoc ou ma documentation efficacement.
    5. Les "metrics" (plugin eclipse metrics) ne me servent que rarement mais surtout pour auditter du code ne m'appartenant pas. J'utilise neanmoins le plugin Code analysys plugin(CAP) ou celui de IBM alphawork: Structural Analysis for Java (SA4j) néanmoins de temps en temps...

    Mais la véritable APOCALYPSE est survenue chez moi il y a trois ans:

    1. Avec le "Refactoring" ' www.refactoring.com ) il m'est impossible de tout prévoir et c'est la que trés rapidement, le refactoring tool de eclipse m'aide car j'itère des changes atomiques (dans le sens: élémentaire et rapide) très rapidement à   travers tout mon code et cela en permanence. Des méthodes bougent ou disparaissent, je renomme en permanence tout: variables, objects, packages (pour éviter des commentaires à   travers mon code). j'introduit aussi des design patterns.
      Je les utilisent tellement que j'ai définit des racourcis clavier dans le workspace de eclipse.
      Le code devient de plus en plus petit (donc moins de bugs/lignes) et fait de plus en plus de chose (par design). Il se bonnifie avec un risque minimum d'instabilité car
    2. J'utilise des "test unitaires" (Junit www.junit.org) qui m'assure aprés chaque gros refactoring que je n'ai pas perdu de fonctionnalitées, cela me sert aussi à   tester mes interfaces: comment mon code va ètre utilisé?, est ce que les signatures sont bien choisies? y a t'il assez de constructors et d'accessors, et sont t'il pertinents? La plupart du temps cela me force repasser par une étape de refactoring dans mon code.

    Est ce la bonne facon de developper? cela dépend des situations, du domaine ou vous travaillez et de vous bien sur.

    Est t'on forcément plus lent? oui et non, cette méthode est déroutante de prime abord mais elle respecte la théorie de l'évolution biologique, génération après génération (refactoring - design - refactoring - unit test) le code devient meilleur.

    Attention: on est pas forcément plus lent, mais cette méthode n'est pas très adaptée au problèmes pointues: on peut se prendre des murs sans cesse (et donc réimplémenter-refactorer) si on ne réflechit pas assez au préalable.

    D'un autre coté, ce qui est certain, c'est que écrire des frameworks est forcément plus long et plus dur que, en caricaturant, faire un main() de 150 lignes (mon dieu, cela se voit encore trop souvent). L'interèt de l'existence d'un framework est dans la réutilisation par d'autres personnes de votre code, et le fait que vous avez deja réalisés pour eux les taches les plus difficiles, mais tout en leur laissant la liberté de spécialiser votre code au besoin.

    Dans les composants java du coté serveur que je réalise pour l'ecommerce d'assurance vie, cela a toujours fonctionné. En tout cas pour moi....