- Amin Mohammed
amin.mohammed@gmail.com
Singleton
Factory
Factory Method
Abstract Factory
Builder
Prototype
Object Pool
Those are also known as parameterized Factories
Provides an abstraction or an interface and lets subclass or implementing classes decide which class or method should be instantiated or called, based on the conditions or parameters given.
Creates objects without exposing the instantiation logic to the client.
refers to the newly created object through a common interface
The implementation is really simple
The client needs a product, but instead of creating it directly using the new operator, it asks the factory object for a new product, providing the information about the type of object it needs.
The factory instantiates a new concrete product and then returns to the client the newly created product(casted to abstract product class).
The client uses the products as abstract products without being aware about their concrete implementation.
Related patterns include
* Abstract Factory , which is a layer higher than a factory method.
* Template method, which defines a skeleton of an algorithm to defer some steps to subclasses or avoid subclasses
* Prototype, which creates a new object by copying an instance, so it reduces subclasses.
* Singleton, which makes a returned factory method unique.
Probably the factory pattern is one of the most used patterns.
For example a graphical application works with shapes. In our implementation the drawing framework is the client and the shapes are the products. All the shapes are derived from an abstract shape class (or interface). The Shape class defines the draw and move operations which must be implemented by the concrete shapes. Let's assume a command is selected from the menu to create a new Circle. The framework receives the shape type as a string parameter, it asks the factory to create a new shape sending the parameter received from menu. The factory creates a new circle and returns it to the framework, casted to an abstract shape. Then the framework uses the object as casted to the abstract class without being aware of the concrete object type.
The advantage is obvious: New shapes can be added without changing a single line of code in the framework(the client code that uses the shapes from the factory). As it is shown in the next sections, there are certain factory implementations that allow adding new products without even modifying the factory class.
The generating method can be written so that it can generate more types of Product objects, using a condition (entered as a method parameter or read from some global configuration parameters - see abstract factory pattern) to identify the type of the object that should be created, as below:
public class ProductFactory{
public Product createProduct(String ProductID){
if (id==ID1)
return new OneProduct();
if (id==ID2) return
return new AnotherProduct();
... // so on for the other Ids
return null; //if the id doesn't have any of the expected values
}
...
}
This implementation is the most simple and intuitive (Let's call it noob implementation). The problem here is that once we add a new concrete product call we should modify the Factory class. It is not very flexible and it violates open close principle. Of course we can subclass the factory class, but let's not forget that the factory class is usually used as a singleton. Subclassing it means replacing all the factory class references everywhere through the code.
To illustrate how to use factory design pattern with class level implementation, here is a real world example. A company has a website to display testing result from a plain text file. Recently, the company purchased a new machine which produces a binary data file, another new machine on the way, it is possible that one will produce different data file. How to write a system to deal with such change. The website just needs data to display. Your job is to provide the specified data format for the website.
Here comes a solution. Use an interface type to converge the different data file format. The following is a skeleton of implementation.
//Let's say the interface is Display
interface Display {
//load a file
public void load(String fileName);
//parse the file and make a consistent data type
public void formatConsistency();
}
//deal with plain text file
class CSVFile implements Display{
public void load(String textfile) {
System.out.println("load from a txt file");
}
public void formatConsistency() {
System.out.println("txt file format changed");
}
}
//deal with XML format file
class XMLFile implements Display {
public void load(String xmlfile) {
System.out.println("load from an xml file");
}
public void formatConsistency() {
System.out.println("xml file format changed");
}
}
//deal with binary format file
class DBFile implements Display {
public void load(String dbfile) {
System.out.println("load from a db file");
}
public void formatConsistency() {
System.out.println("db file format changed");
}
}
//Test the functionality
class ExampleFactory {
public static void main(String[] args) {
Display display = null;
//use a command line data as a trigger
if (args[0].equals("1"))
display = new CSVFile();
else if (args[0].equals("2"))
display = new XMLFile();
else if (args[0].equals("3"))
display = new DBFile();
else
System.exit(1);
//converging code follows
display.load("");
display.formatConsistency();
}
}
//after compilation and run it
C:\>java ExampleFactory 1
load from a txt file
txt file format changed
C:\>java ExampleFactory 2
load from an xml file
xml file format changed
C:\>java ExampleFactory 3
load from a db file
db file format changed
In the future, the company may add more data file with different format, a programmer just adds a new class in accordingly. Such design saves a lot of code and is easy to maintain.
Abstract Factory
Definition:
Provides one level of interface higher than the factory pattern. It is used to return one of several factories.
Creates families of related or dependent objects like Kit.
Provides a class library of products, exposing interface not implementation.
Needs to isolate concrete classes from their super classes.
A system needs independent of how its products are created, composed, and represented.
Try to enforce a constraint.
An alternative to Facade to hide platform-specific classes
Easily extensible to a system or a family
Abstract Factory offers the interface for creating a family of related objects, without explicitly specifying their classes.
Related patterns include
* Factory method, which is often implemented with an abstract factory.
* Singleton, which is often implemented with an abstract factory.
* Prototype, which is often implemented with an abstract factory.
* Facade, which is often used with an abstract factory by providing an interface for creating implementing class.
The classes that participate to the Abstract Factory pattern are:
AbstractFactory - declares a interface for operations that create abstract products.
ConcreteFactory - implements operations to create concrete products.
AbstractProduct - declares an interface for a type of product objects.
Product - defines a product to be created by the corresponding ConcreteFactory; it implements the AbstractProduct interface.
Client - uses the interfaces declared by the AbstractFactory and AbstractProduct classes.
Example :
abstract class AbstractProductA{
public abstract void operationA1();
public abstract void operationA2();
}
class ProductA1 extends AbstractProductA{
ProductA1(String arg){
System.out.println("Hello "+arg);
} // Implement the code here
public void operationA1() { };
public void operationA2() { };
}
class ProductA2 extends AbstractProductA{
ProductA2(String arg){
System.out.println("Hello "+arg);
} // Implement the code here
public void operationA1() { };
public void operationA2() { };
}
abstract class AbstractProductB{
//public abstract void operationB1();
//public abstract void operationB2();
}
class ProductB1 extends AbstractProductB{
ProductB1(String arg){
System.out.println("Hello "+arg);
} // Implement the code here
}
class ProductB2 extends AbstractProductB{
ProductB2(String arg){
System.out.println("Hello "+arg);
} // Implement the code here
}
abstract class AbstractFactory{
abstract AbstractProductA createProductA();
abstract AbstractProductB createProductB();
}
class ConcreteFactory1 extends AbstractFactory{
AbstractProductA createProductA(){
return new ProductA1("ProductA1");
}
AbstractProductB createProductB(){
return new ProductB1("ProductB1");
}
}
class ConcreteFactory2 extends AbstractFactory{
AbstractProductA createProductA(){
return new ProductA2("ProductA2");
}
AbstractProductB createProductB(){
return new ProductB2("ProductB2");
}
}
//Factory creator - an indirect way of instantiating the factories
class FactoryMaker{
private static AbstractFactory pf=null;
static AbstractFactory getFactory(String choice){
if(choice.equals("a")){
pf=new ConcreteFactory1();
}else if(choice.equals("b")){
pf=new ConcreteFactory2();
} return pf;
}
}
// Client
public class Client{
public static void main(String args[]){
AbstractFactory pf=FactoryMaker.getFactory("a");
AbstractProductA product=pf.createProductA();
//more function calls on product
}
}
Applicability & Examples
We should use the Abstract Factory design pattern when:
the system needs to be independent from the way the products it works with are created.
the system is or should be configured to work with multiple families of products.
a family of products is designed to work only all together.
the creation of a library of products is needed, for which is relevant only the interface, not the implementation, too.
An application usually needs only one instance of the ConcreteFactory class per family product. This means that it is best to implement it as a Singleton.
The AbstractFactory class only declares the interface for creating the products. It is the task of the ConcreteProduct class to actually create the products. For each family the best idea is applying the Factory Method design pattern. A concrete factory will specify its products by overriding the factory method for each of them. Even if the implementation might seem simple, using this idea will mean defining a new concrete factory subclass for each product family, even if the classes are similar in most aspects.
For simplifying the code and increase the performance the Prototype design pattern can be used instead of Factory Method, especially when there are many product families. In this case the concrete factory is initiated with a prototypical instance of each product in the family and when a new one is needed instead of creating it, the existing prototype is cloned. This approach eliminates the need for a new concrete factory for each new family of products.
Cloning an object by reducing the cost of creation.
overriding method is a kind of prototype pattern.
Related patterns include
* Abstract Factory, which is often used together with prototype. An abstract factory may store some prototypes for cloning and returning objects.
* Composite, which is often used with prototypes to make a part-whole relationship.
* Decorator, which is used to add additional functionality to the prototype.
The clients will use the interface of the prototype manager to handle prototypes at run-time and will ask for permission before using the Clone() method.
There is not much difference between an implementation of a prototype which uses a prototype manager and a factory method implemented using class registration mechanism. Maybe the only difference consists in the performance.
A small discussion appears when talking about how deep or shallow a clone should be: a deep clone clones the instance variables in the cloning object while a shallow clone shares the instance variables between the clone and the original. Usually, a shallow clone is enough and very simple, but cloning complex prototypes should use deep clones so the clone and the original are independent, a deep clone needing its components to be the clones of the complex object’s components.
There are cases when the internal states of a clone should be initialized after it is created. This happens because these values cannot be passed to the Clone() method, that uses an interface which would be destroyed if such parameters were used. In this case the initialization should be done by using setting and resetting operations of the prototype class or by using an initializing method that takes as parameters the values at which the clone’s internal states should be set.
Prototype Manager – implemented usually as a hashtable keeping the object to clone. When use it, prototype become a factory method which uses cloning instead of instantiation.
Deep Clones vs. Shallow Clones – when we clone complex objects which contains other objects, we should take care how they are cloned. We can clone contained objects also (deep cloning) or we can the same reference for them, and to share them between cloned container objects.
Initializing Internal States – there are certain situations when objects need to be initialized after they are created.
The example here we will take will be of a plant cell. This example is a bit different from the actual cloning in a way that cloning involves making a copy of the original one. Here, we break the cell in two and make two copies and the original one does not exist. But, this example will serve the purpose. Let’s say the Mitotic Cell Division in plant cells.
Let’s take a class PlantCell having a method split(). The plant cell will implement the interface Cloneable.
Following is the sample code for class PlantCell.
PlantCell.java
Now let’s see, how this split method works for PlantCell class. We will make another class CellDivision and access this method.
CellDivision.java
package creational.prototype;
/**
* Shows how to use the clone.
*/
public class CellDivision {
public static void main(String[] args) {
PlantCell cell = new PlantCell();
// create a clone
PlantCell newPlantCell = (PlantCell)cell.split();
}
}// End of class
Definition
Construct a complex object from simple objects step by step.
Make a complex object by specifying only its type and content. The built object is shielded from the details of its construction.
Want to decouple the process of building a complex object from the parts that make up the object.
Isolate code for construction and representation.
Give you finer control over the construction process.
Related patterns include
Abstract Factory, which focuses on the layer over the factory pattern (may be simple or complex), whereas a builder pattern focuses on building a complex object from other simple objects.
Composite, which is often used to build a complex object.
To build a house, we will take several steps:
build foundation,
build frame,
build exterior,
build interior.
Let's use an abstract class HouseBuilder to define these 4 steps. Any subclass of HouseBuilder will follow these 4 steps to build house (that is to say to implement these 4 methodin the subclass). Then we use a WorkShop class to force the order of these 4 steps (that is to say that we have to build interior after having finished first three steps). The TestBuilder class is used to test the coordination of these classes and to check the building process.
import java.util.*;
class WorkShop {
//force the Sequence of building process
public void construct(HouseBuilder hb) {
hb.buildFoundation();
hb.buildFrame();
hb.buildExterior();
hb.buildInterior();
}
}
//set steps for building a house
abstract class HouseBuilder {
protected House house = new House();
protected String showProgress() {
return house.toString();
}
abstract public void buildFoundation();
abstract public void buildFrame();
abstract public void buildExterior();
abstract public void buildInterior();
}
class OneStoryHouse extends HouseBuilder {
public OneStoryHouse(String features) {
house.setType(this.getClass() + " " + features);
}
public void buildFoundation() {
//doEngineering()
//doExcavating()
//doPlumbingHeatingElectricity()
//doSewerWaterHookUp()
//doFoundationInspection()
house.setProgress("foundation is done");
}
public void buildFrame() {
//doHeatingPlumbingRoof()
//doElectricityRoute()
//doDoorsWindows()
//doFrameInspection()
house.setProgress("frame is done");
}
public void buildExterior() {
//doOverheadDoors()
//doBrickWorks()
//doSidingsoffitsGutters()
//doDrivewayGarageFloor()
//doDeckRail()
//doLandScaping()
house.setProgress("Exterior is done");
}
public void buildInterior() {
//doAlarmPrewiring()
//doBuiltinVacuum()
//doInsulation()
//doDryWall()
//doPainting()
//doLinoleum()
//doCabinet()
//doTileWork()
//doLightFixtureBlinds()
//doCleaning()
//doInteriorInspection()
house.setProgress("Interior is under going");
}
}
class TwoStoryHouse extends HouseBuilder {
public TwoStoryHouse(String features) {
house.setType(this.getClass() + " " + features);
}
public void buildFoundation() {
//doEngineering()
//doExcavating()
//doPlumbingHeatingElectricity()
//doSewerWaterHookUp()
//doFoundationInspection()
house.setProgress("foundation is done");
}
public void buildFrame() {
//doHeatingPlumbingRoof()
//doElectricityRoute()
//doDoorsWindows()
//doFrameInspection()
house.setProgress("frame is under construction");
}
public void buildExterior() {
//doOverheadDoors()
//doBrickWorks()
//doSidingsoffitsGutters()
//doDrivewayGarageFloor()
//doDeckRail()
//doLandScaping()
house.setProgress("Exterior is waiting to start");
}
public void buildInterior() {
//doAlarmPrewiring()
//doBuiltinVacuum()
//doInsulation()
//doDryWall()
//doPainting()
//doLinoleum()
//doCabinet()
//doTileWork()
//doLightFixtureBlinds()
//doCleaning()
//doInteriorInspection()
house.setProgress("Interior is not started yet");
}
}
class House {
private String type = null;
private List features = new ArrayList();
public House() {
}
public House(String type) {
this.type = type;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setProgress(String s) {
features.add(s);
}
public String toString() {
StringBuffer ff = new StringBuffer();
String t = type.substring(6);
ff.append(t + "\n ");
for (int i = 0; i < features.size(); i ++) {
ff.append(features.get(i) + "\n ");
}
return ff.toString();
}
}
class TestBuilder {
public static void main(String[] args) {
HouseBuilder one = new OneStoryHouse("2 bedrooms, 2.5 baths, 2-car garage, 1500 sqft");
HouseBuilder two = new TwoStoryHouse("4 bedrooms, 4 baths, 3-car garage, 5000 sqft");
WorkShop shop = new WorkShop();
shop.construct(one);
shop.construct(two);
System.out.println("Check house building progress: \n");
System.out.println(one.showProgress());
System.out.println(two.showProgress());
}
}
//need jdk1.5 above to compile
C:\ Command Prompt
To fine tune the above example, every do method can be designed as a class. Similar functional class can be designed once and used by other classes. e.g. Window, Door, Kitchen, etc.
Another example, such as writing a Pizza program. Every gradient can be designed as a class. One pizza at least consists of several gradients. Different pizza has different gradients. A builder pattern may be adopted.
You use the builder pattern to
1. Encapsulate the construction of a complex object.
2. Create an object in multiple steps.
You typically use factories to create an object in a single step. But if you need to create an object in multiple steps and if you need the flexibility to vary those steps during creation (for example, some times you may want to skip some steps and sometimes include them), you would use the builder pattern. You will not get the flexibility to do this if you use factories, because factories create the product in a single step and return you the product. Builders are typically used to build a composite structure. A good example would be a vacation planner object. A vacation planner is made of a number of days. Each day is made up of a number of events like checking into hotel, dinner etc. Now this is going to vary for each person. So you really need a lot of flexibility to build the vacation planner object for different people and at the same time encapsulate its construction. Using the builder pattern, you can define a builder interface with methods like buildDay(), buildDinner(), buildOuting() etc . You can then compose this builder interface with a class and call these methods in any order and combination that you want to create the planner object in several steps. Hope this clarifies the flexibility builder gives over factories and when you would use them.
The subtle difference between the builder pattern and the factory pattern is that in builder pattern, the user is given the choice to create the type of object he/she wants but the construction process is the same. But with the factory method pattern the factory decides how to create one of several possible classes based on data provided to it.
any good builder pattern will have a composite pattern embedded. The output of the construction process is a composite and same construction process can be used to create different composites. Composites again can be recursive in nature.
Practical situation you do not generally start off using Builder pattern.You start of with Factory . If the requirements specs are clear enough to indicate flexibility we can think of adding Abstract factories and Builders with embedded composite for recursive hierarchy .
Ensure that only one instance of a class is created.
Provide a global point of access to the object.
Implementation
The implementation involves a static member in the "Singleton" class, a private constructor and a static public method that returns a reference to the static member.
The Singleton Pattern defines a getInstance operation which exposes the unique instance which is accessed by the clients. getInstance() is a class operation and is responsible for creating its own unique instance in case it is not created yet.
class Singleton
{
private static Singleton m_instance;
private Singleton()
{
...
}
public static synchronized Singleton getInstance()
{
if (m_instance == null)
m_instance = new Singleton();
return m_instance;
}
...
public void doSomething()
{
...
}
}
In the code above it can be seen that the getInstance method ensure that only one instance of the class is created. The constructor should not be accessible from outside of the class to ensure that the only way of instantiating the class to be through the getInstance method.
The getInstance method is used also to provide a global point of access to the object and it can be used like this:
Singleton.getInstance().doSomething();
According to the definition the singleton pattern should be used when there must be exactly one instance of a class, and when it must be accessible to clients from a global access point. Here are some real situations where the singleton is used:
The adapter pattern can be described as follows. When you have to implement an interface, but you want to use another class’ (or interface’s) methods in order to implement it you are using the Adapter Pattern. An example will illustrate this much better than this definition.
Lets say I have an AddressBook, and I wish to display this AddressBook to a JTable. One solution (without using the Adapter Pattern) is to have my AddressBook implement the TableModel. This is not such a good idea, because I don’t want my AddressBook class (or object model) to be tied to Swing.
I can provide a nice solution to this problem by using the Adapter Pattern. Instead of implementing the TableModel directly on the AddressBook, I instead create an intermediary adapter class. This adapter class actually uses the AddressBook methods in order implement the TableModel. So I would call this class the AddressBookTableAdapter. Review the code snippets below to get an idea of how this is implemented.
There is no need for an Adapter to subclass the AddressBook class. In fact, you should use the Delegation Pattern, instead of using subclass. The example below uses the Delegation Pattern instead of subclassing.
Now that you have seen the Adapter pattern, you ask why use it? Well, the answer to this question has already been provided in the example problem definition. You don’t want your object models implementing JavaVM specific interfaces becuase they might change in the future. Also, by implementing Swing interfaces directly into your object models, you make your code messy by introducing Swing event handling code there.
The Bridge Pattern is used to separate out the interface from its implementation. Doing this gives the flexibility so that both can vary independently.
Motivation:
Sometimes an abstraction should have different implementations; consider an object that handles persistence of objects over different platforms using either relational databases or file system structures (files and folders). A simple implementation might choose to extend the object itself to implement the functionality for both file system and RDBMS. However this implementation would create a problem; Inheritance binds an implementation to the abstraction and thus it would be difficult to modify, extend, and reuse abstraction and implementation independently.
The bridge pattern applies when there is a need to avoid permanent binding between an abstraction and an implementation and when the abstraction and implementation need to vary independently. Using the bridge pattern would leave the client code unchanged with no need to recompile the code.
Related patterns include
Abstract Factory, which can be used to create and configure a particular bridge.
Adapter, which makes unrelated classes work together, whereas a bridge makes a clear-cut between abstraction and implementation.
Example 2: for this is like the electric equipments you have at home and their switches. For e.g., the switch of the fan. The switch is the interface and the actual implementation is the Running of the fan once its switched-on. Still, both the switch and the fan are independent of each other. Another switch can be plugged in for the fan and this switch can be connected to light bulb.
http://www.allapplabs.com/java_design_patterns/bridge_pattern.htm
Example 3 :
If you have a question database, you may want to develop a program to display it based on the user selection. The following is a simple example to show how to use a Bridge pattern to decouple the relationship among the objects.
http://www.javacamp.org/designPattern/