1) Adapter (Structural Design Pattern) http://java.dzone.com/articles/design-patterns-uncovered-0 Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. Consider that we have a third party library that provides sorting functionality through it's NumberSorter class. This is our Adaptee. Our Client deals with primitive arrays rather than Lists. For the sake of this example, lets say we can't change the client to use Lists. We've provided a Sorter interface that expects the client input. This is our target. Finally, the SortListAdapter implements our target interface and deals with our adaptee, NumberSorter. /*Adaptee*/ 01./* 02.* This is our adaptee, a third party implementation of a 03.* number sorter that deals with Lists, not arrays. 04.*/ 05.public class NumberSorter 06.{ 07.public List<Integer> sort(List<Integer> numbers) 08.{ 09.//sort and return 10.return new ArrayList<Integer>(); 11.} 12. 13.} 1 /*Client*/ 1.int[] numbers = new int[]{34, 2, 4, 12, 1}; 2. 3.Sorter sorter = new SortListAdapter(); 4.sorter.sort(numbers); /*Target Interface*/ 1.//this is our Target interface 2.public interface Sorter 3.{ 4.public int[] sort(int[] numbers); 5.} /*Adapter*/ 01.public class SortListAdapter implements Sorter 02.{ 03. 04.@Override 05.public int[] sort(int[] numbers) 06.{ 07.//convert the array to a List 08.List<Integer> numberList = new ArrayList<Integer>(); 09. 10.//call the adapter 11.NumberSorter sorter = new NumberSorter(); 12.numberList = sorter.sort(numberList); 13. 14.//convert the list back to an array and return 15. 16.return sortedNumbers; 17.} 18. 19.} 2) Facade (Structural Design Pattern) http://java.dzone.com/articles/design-patterns-uncovered-1 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. 2 Let's take a travel agent site for example, that allows you to book hotels and flights. We have a HotelBooker: Both of these have Hotel and Flight datatypes, which the client has knowledge about. They could be provided in the same package as the Facade for example. The TravelFacade class allows the user to get their Hotel and Flight information in one call: 01.public class HotelBooker /*Package1 Class1*/ 02.{ 03. 04.public ArrayList<Hotel> getHotelNamesFor(Date from, Date to) 05.{ 06.//returns hotels available in the particular date range 07. 08.} 09. 10.} 01.public class FlightBooker /*Package2 Class1*/ 02.{ 03. 04.public ArrayList<Flight> getFlightsFor(Date from, Date to) 05.{ 06.//returns flights available in the particular date range 07. 08.} 09. 10.} 01.public class TravelFacade 02.{ 03. 04.private HotelBooker hotelBooker; 05.private FlightBooker flightBooker; 06. 07.public void getFlightsAndHotels(Date from, Data to) 08.{ 09.ArrayList<Flight> flights = flightBooker.getFlightsFor(from, to); 10.ArrayList<Hotel> hotels = hotelBooker.getHotelsFor(from, to); 11. 12.//process and return 13. 14.} 15. 16.} 01.public class Client 3 02.{ 03. 04.public static void main(String[] args) 05.{ 06.TravelFacade facade = new TravelFacade(); 07.facade.getFlightsAndHotels(from, to); 08.} 09.} 4 3) Singleton (Creational Design Pattern) http://java.dzone.com/articles/design-patterns-singleton Ensure a class has only one instance and provide a global point of access to it. When you need to ensure there's one instance of an object, available to a number of other classes, you may want to use the Singleton pattern. Singletons are used a lot where you need to provide a registry, or something like a thread pool. Logging is also another popular use of Singletons, providing one single access point to an applications log file. This example will show how to put together the classic Singleton in Java, without thinking about the threading complications which we discuss later on in this article. The Singleton class has some characteristics that we generally want to ensure two things: We lazily load our singleton based on the first request for access to it. There is no other way of instantiating our Singleton /*Singleton*/ 01.public class Singleton 02.{ 03.private Singleton instance; 04. 05.private Singleton() 06.{ 07.} 08. 09.public static Singleton getInstance() 10.{ 11.if(instance==null) 12.{ 13.instance = new Singleton(); 14.} 15.return instance; 16.} 17. 18. 19.} /*Client*/ 1.//access the singleton 2.Singleton singleton = Singleton.getInstance(); 3.//use the singleton 5 4) Factory Method (Creational Design Pattern) http://java.dzone.com/articles/design-patterns-factory Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses Now, let's take a look at the diagram definition of the Factory Method pattern. The Creator hides the creation and instantiation of the Product from the client. This is a benefit to the client as they are now insulated from any future changes - the Creator will look after all of their creation needs, allowing to decoupling. Furthermore, once the Creator and the Product conform to an interface that the client knows, the client doesn't need to know about the concrete implementations of either. The factory method pattern really encourages coding to an interface in order to deal with future change. Here the Creator provides an interface for the creation of objects, known as the factory method. All other methods in our abstract Creator are written only to operate on the Products created in theConcreteCreator. The Creator doesn't create the products - that work is done by it's subclasses, such as ConcreateCreator. The idea behind the Factory Method pattern is that it allows for the case where a client doesn't know what concrete classes it will be required to create at runtime, but just wants to get a class that will do the job. The FactoryMethod builds on the concept of a simple Factory, but lets the subclasses decide which implementation of the concrete class to use. You'll see factories used in logging frameworks, and in a lot of scenarios where the client doesn't need to know about the concrete implementations. It's a good approach to encapsulation.This example will use the concept of a logger to illustrate the factory method. First, let's create our Product interface, in this case Logger: 6 1.//interface (Product) 2.public interface Logger { 3. 4.public void log(String message); 5.} 01.//concrete implementation of the Logger (Concrete Product) 02.public class XMLLogger implements Logger { 03. 04.public void log(String message) { 05.//log to xml 06.System.err.println("logging"); 07.} 08. 09.} 01.//the abstract Creator 02.public abstract class AbstractLoggerCreator 03.{ 04.//the factory method 05.public abstract Logger createLogger(); 06. 07. 08.//the operations that are implemented for all LoggerCreators 09.//like anOperation() in our diagram 10.public Logger getLogger() 11.{ 12.//depending on the subclass, we'll get a particular logger. 13.Logger logger = createLogger(); 14. 15.//could do other operations on the logger here 16. 17.return logger; 18.} 19. 20.} 01.//ConcreteCreator 02.public class XMLLoggerCreator extends AbstractLoggerCreator{ 03. 04.@Override 05.public Logger createLogger() { 06.XMLLogger logger = new XMLLogger(); 07.return logger; 08.} 09. 10.} 7 01.public class Client { 02.private void someMethodThatLogs(AbstractLoggerCreator logCreator) 03.{ 04.Logger logger = logCreator.createLogger(); 05.logger.log("message"); 06. 07.} 08. 09. 10. 11.public static void main(String[] args) 12.{ 13.//for the purposes of this example, create an XMLLoggerCreator directly, 14.//but this would normally be passed to constructor for use. 15.AbstractLoggerCreator creator = new XMLLoggerCreator(); 16. 17.Client client = new Client(); 18.client.someMethodThatLogs(creator); 19.} 20. 21.} 5) Observer (Behavioral Design Pattern) http://java.dzone.com/articles/design-patterns-uncovered Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Before we get into the theory and code behind the Observer, let's take a look at a real world example, such as RSS feeds. When I want to get updates from a particular feed, I add it to my feed reader. Any time that the RSS feed has an update, it will appear in my reader automatically. This is the Observer pattern in action, a publisher/subscriber relationship with one source having many subscribers. The idea behind the pattern is simple - one of more Observers are interested in the state of aSubject and register their interest with the Subject by attaching themselves. When something changes in our Subject that the Observer may be interested in, a notify message is sent, which calls the update method in each Observer. When the Observer is no longer interested in the Subject's state, they can simply detatchthemselves. 8 In our example, the subject will be a DataStore, with a Screen class as the observer.First, let's make our DataStore class observable by extending the java.util.Observable class. This means that our DataStore has all the methods and functionality available to make it a Subject, according to our pattern. 01.import java.util.Observable; 02. 03.public class DataStore extends Observable 04.{ 05. 06.private String data; 07. 08.public String getData() 09.{ 10.return data; 11.} 12. 13.public void setData(String data) 14.{ 15.this.data =data; 16.//mark the observable as changed 9 17.setChanged(); 18.} 19.} 01.public class Screen implements Observer { 02. 03.@Override 04.public void update(Observable o, Object arg) { 05. 06.//act on the update 07.} 08. 09.} 1.Screen screen = new Screen(); 2. 3.DataStore dataStore = new DataStore(); 4.//register observer 5.dataStore.addObserver(screen); 6. 1.//send a notification 2.dataStore.notifyObservers(); 10 6) Strategy (Behavioral Design Pattern) http://java.dzone.com/articles/design-patterns-strategy Defines a set of encapsulated algorithms that can be swapped to carry out a specific behaviour In the diagram Context is composed of a Strategy. The context could be anything that would require changing behaviours - a class that provides sorting functionality perhaps. The Strategy is simply implemented as an interface, so that we can swap ConcreteStrategys in and out without effecting our Context The Strategy pattern is to be used where you want to choose the algorithm to use at runtime. A good use of the Strategy pattern would be saving files in different formats, running various sorting algorithms, or file compression. The Strategy pattern provides a way to define a family of algorithms, encapsulate each one as an object, and make them interchangeable. Let's use the example of a file compression tool - where we create either zip or rar files. First we'll need a strategy: 11 1.//Strategy Interface 2.public interface CompressionStrategy 3.{ 4.public void compressFiles(ArrayList<File> files); 5.} 01.public class ZipCompressionStrategy implements CompressionStrategy 02.{ 03. 04.public void compressFiles(ArrayList<File> files) 05.{ 06.//using ZIP approach 07.} 08. 09.} 01.public class RarCompressionStrategy implements CompressionStrategy 02.{ 03. 04.public void compressFiles(ArrayList<File> files) 05.{ 06.//using RAR approach 07.} 08. 09.} 01.public class CompressionContext 02.{ 03.private CompressionStrategy strategy; 04. 05.//this can be set at runtime by the application preferences 06.public void setCompressionStrategy(CompressionStrategy strategy) 07.{ 08.this.strategy = strategy; 09.} 10. 11.//use the strategy 12.public void createArchive(ArrayList<File> files) 13.{ 14.strategy.compressFiles(files); 15.} 16. 17.} 01.public class Client 02.{ 03. 04.public static void main(String[] args) 05.{ 06.CompressionContext ctx = new CompressionContext(); 07.//we could assume context is already set by preferences 08.ctx.setCompressionStrategy(new ZipCompressionStrategy()); 09.//get a list of files 10.... 11.ctx.createArchive(fileList); 12. 13.} 14.} 12 7) Composite (Structural Design Pattern) http://java.dzone.com/articles/design-patterns-composite Allow you to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. The Component interface defines the interface that all objects in the composed system need to use, whether they are leafs (simple objects) or compositions. However, this is usually implemented as an abstract class providing some default behaviour for the add, remove and getChild methods. The Leaf has no children, and as such only needs to implement the operation method. TheComposite needs to do more, as it also contains components. The composite will more than likely need to implement the operation method, which is considered as a Leaf-related operation. Sometimes this may not make sense for a composite to implement. Usually, the Composite will implement methods by delegating to the children. The Client simply uses the Component interface to manipulate the objects. This pattern should be used when you want to represent objects in a hierachical fashion, or you need objects and composites to be treated uniformly. Graphics frameworks are the most common use of this pattern. The base Graphic object provides the base class for all other graphic objects, such as Line, Rectangle, which provide their own implementations of the pGraphics is a great example of how the Composite pattern works, so I'll use that here. First, we create an general interface for our graphics object. The main thing is that we have a paint method. Each graphic could be composed of other graphics too, so we'll need to provide a way to contain these objects. paint()/draw() method. The Composite pattern is frequently used for abstract syntax tree representations. Graphics is a great example of how the Composite pattern works, so I'll use that here. First, we create an general interface for our graphics object. The main thing is that we have a paint method. Each graphic could be composed of other graphics too, so we'll need to provide a way to contain these objects. 13 1.//Component interface 2.public interface Graphic 3.{ 4.public void add(Graphic g); 5.public void remove(Graphic g); 6.public Graphic get(int index); 7.public void paint(); 8.} 01.//Composite 02.public class CompositeGraphic implements Graphic 03.{ 04.private List<Graphic> children = new ArrayList<Graphic>(); 05. 06.public void paint() 07.{ 08.//run the paint operation for each child 09.for(Graphic g: children) 10.{ 11.g.paint(); 12.} 13.} 14. 15. 16.public void add(Graphic g) 17.{ 18.children.add(g); 19.} 20. 21.public void remove(Graphic g) 22.{ 23.if(children.contains(g)) 24.{ 25.children.remove(g); 26.} 27.} 28. 29.public Graphic get(int index) 30.{ 31.if(index < children.size()) 32.{ 33.return children.get(index); 34.} 35.} 36. 37. 38.} 01.//Leaf 02.public class SimpleGraphic implements Graphic 03.{ 04. 05.public void paint() 06.{ 07.//run the paint operation 08.} 09. 10./** 11.* Because we have no children, these operations will do nothing 12.**/ 14 13.public void add(Graphic g) 14.{ 15.//unsupported operation 16.} 17. 18.public void remove(Graphic g) 19.{ 20.//unsupported operation 21.} 22. 23.public void get(int index) 24.{ 25.//unsupported operation 26.} 27.} 01.//Client. 02.public class GraphicsClient 03.{ 04./** 05.* Given a graphics context, client can just call paint, without worrying if this is a composite or leaf 06.**/ 07.public void paint(Graphics g) 08.{ 09.g.paint(); 10.} 11.} 15 8) Abstract Factory (Creational Design Pattern) http://java.dzone.com/articles/design-patterns-abstract-factory Provides an interface for creating families of related or dependent objects without specifying their concrete classes. The AbstractFactory defines the interface that all of the concrete factories will need to implement in order to product Products. ConcreteFactoryA and ConcreteFactoryB have both implemented this interface here, creating two seperate families of product. Meanwhile, AbstractProductA andAbstractProductB are interfaces for the different types of product. Each factory will create one of each of these AbstractProducts. The Client deals with AbstractFactory, AbstractProductA and AbstractProductB. It doesn't know anything about the implementations. The actual implementation of AbstractFactory that the Clientuses is determined at runtime. As you can see, one of the main benefits of this pattern is that the client is totally decoupled from the concrete products. Also, new product families can be easily added into the system, by just adding in a new type of ConcreteFactory that implements AbstractFactory, and creating the specific Product implementations. 16 The pattern is best utilised when your system has to create multiple families of products or you want to provide a library of products without exposing the implementation details. As you'll have noticed, a key characteristic is that the pattern will decouple the concrete classes from the client. An example of an Abstract Factory in use could be UI toolkits. Across Windows, Mac and Linux, UI composites such as windows, buttons and textfields are all provided in a widget API like SWT. However, the implementation of these widgets vary across platforms. You could write a platform independent client thanks to the Abstract Factory implementation. 17 1.//Our AbstractProduct 2.public interface Window 3.{ 4. 5.public void setTitle(String text); 6. 7.public void repaint(); 8.} 01.//ConcreteProductA1 02.public class MSWindow implements Window 03.{ 04.public void setTitle() 05.{ 06.//MS Windows specific behaviour 07.} 08. 09.public void repaint() 10.{ 11.//MS Windows specific behaviour 12.} 13.} 01.//ConcreteProductA2 02.public class MacOSXWindow implements Window 03.{ 04.public void setTitle() 05.{ 06.//Mac OSX specific behaviour 07.} 08. 09.public void repaint() 10.{ 11.//Mac OSX specific behaviour 12.} 13.} 1.//AbstractFactory 2.public interface AbstractWidgetFactory 3.{ 4.public Window createWindow(); 5.} 01.//ConcreteFactory1 02.public class MsWindowsWidgetFactory 03.{ 04.//create an MSWindow 05.public Window createWindow() 06.{ 07.MSWindow window = new MSWindow(); 18 08.return window; 09.} 10.} 01.//ConcreteFactory2 02.public class MacOSXWidgetFactory 03.{ 04.//create a MacOSXWindow 05.public Window createWindow() 06.{ 07.MacOSXWindow window = new MacOSXWindow(); 08.return window; 09.} 10.} 01.//Client 02.public class GUIBuilder 03.{ 04.public void buildWindow(AbstractWidgetFactory widgetFactory) 05.{ 06.Window window = widgetFactory.createWindow(); 07.window.setTitle("New Window"); 08.} 09.} 01.public class Main{ 02.public static void main(String[] args) 03.{ 04.GUIBuilder builder = new GUIBuilder(); 05.AbstractWidgetFactory widgetFactory = null; 06.//check what platform we're on 07.if(Platform.currentPlatform()=="MACOSX") 08.{ 09.widgetFactory = new MacOSXWidgetFactory(); 10.} 11.else 12.{ 13.widgetFactory = new MsWindowsWidgetFactory(); 14.} 15.builder.buildWindow(widgetFactory); 16.} 17.} 19