Design Pattern Print

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 14

Factory Design Pattern

Motivation
The Factory Design Pattern is maybe the most used pattern in modern languages like Java
and C#. Most probably if you are searching for factory design pattern on the internet most
of the results are about Factory Method and Abstract Factory.

Both of the above mentioned are factories but are different or maybe are just some
extensions of the factory design pattern. The Factory pattern is not included in the GoF
(Gang of Four).

Intent
• creates objects without exposing the instantiation logic to the client.
• refers to the newly created object through a common interface

Implementation

The implementation is really simple

• The client need a product, but instead of creating it directly using the new operator it
asks for a new product to the factory providing some information about the type of
object it needs.
• The factory instantiates a new concrete product and then return to the client the
created product casted as abstract product.
• The client uses the products only as abstract products without being aware about
their concrete implementation.

Factory Method Pattern

Motivation
Also known as Virtual Constructor, the Factory Method is related to the idea on which
libraries work: a library uses abstract classes for defining and maintaining relations between
objects. One type of responsibility is creating such objects. The library knows when an
object needs to be created, but not what kind of object it should create, this being specific
to the application using the library.

The Factory method works just the same way: it defines an interface for creating an object,
but leaves the choice of its type to the subclasses, creation being deferred at run-time. A
simple real life example of the Factory Method is the hotel. When staying in a hotel you first
have to check in. The person working at the front desk will give you a key to your room
after you've paid for the room you want and this way he can be looked at as a “room”
factory. While staying at the hotel, you might need to make a phone call, so you call the
front desk and the person there will connect you with the number you need, becoming a
“phone-call” factory, because he controls the access to calls, too.

Intent
• Defines an interface for creating objects, but let subclasses to decide which class to
instantiate
• Refers to the newly created object through a common interface

Implementation
The pattern basically works as shown below, in the UML diagram:

The participants classes in this pattern are:

• Product defines the interface for objects the factory method creates.
• ConcreteProduct implements the Product interface.
• Creator(also refered as Factory because it creates the Product objects) declares the
method FactoryMethod, which returns a Product object. May call the generating
method for creating Product objects
• ConcreteCreator overrides the generating method for creating ConcreteProduct
objects

All concrete products are subclasses of the Product class, so all of them have the same basic
implementation, at some extent. The Creator class specifies all standard and generic
behavior of the products and when a new product is needed, it sends the creation details
that are supplied by the client to the ConcreteCreator. Having this diagram in mind, it is
easy for us now to produce the code related to it. Here is how the implementation of the
classic Factory method should look:

public interface Product { … }

public abstract class Creator


{
public void anOperation()
{
Product product = factoryMethod();
}

protected abstract Product factoryMethod();


}

public class ConcreteProduct implements Product { … }

public class ConcreteCreator extends Creator


{
protected Product factoryMethod()
{
return new ConcreteProduct();
}
}

public class Client


{
public static void main( String arg[] )
{
Creator creator = new ConcreteCreator();
creator.anOperation();
}
}

Applicability & Examples


The need for implementing the Factory Method is very frequent. The cases are the ones
below:

• when a class can't anticipate the type of the objects it is supposed to create
• when a class wants its subclasses to be the ones to specific the type of a newly
created object

Abstract Factory

Motivation
Modularization is a big issue in today's programming. Programmers all over the world are
trying to avoid the idea of adding code to existing classes in order to make them support
encapsulating more general information. Take the case of a information manager which
manages phone number. Phone numbers have a particular rule on which they get generated
depending on areas and countries. If at some point the application should be changed in
order to support adding numbers form a new country, the code of the application would
have to be changed and it would become more and more complicated.

In order to prevent it, the Abstract Factory design pattern is used. Using this pattern a
framework is defined, which produces objects that follow a general pattern and at runtime
this factory is paired with any concrete factory to produce objects that follow the pattern of
a certain country. In other words, the Abstract Factory is a super-factory which creates
other factories (Factory of factories).
Intent
• Abstract Factory offers the interface for creating a family of related objects, without
explicitly specifying their classes.

Implementation
The pattern basically works as shown below, in the UML diagram:

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.
The AbstractFactory class is the one that determines the actual type of the concrete object
and creates it, but it returns an abstract pointer to the concrete object just created. This
determines the behavior of the client that asks the factory to create an object of a certain
abstract type and to return the abstract pointer to it, keeping the client from knowing
anything about the actual creation of the object.

The fact that the factory returns an abstract pointer to the created object means that the
client doesn't have knowledge of the object's type. This implies that there is no need for
including any class declarations relating to the concrete type, the client dealing at all times
with the abstract type. The objects of the concrete type, created by the factory, are
accessed by the client only through the abstract interface.

The second implication of this way of creating objects is that when the adding new concrete
types is needed, all we have to do is modify the client code and make it use a different
factory, which is far easier than instantiating a new type, which requires changing the code
wherever a new object is created.

The classic implementation for the Abstract Factory pattern is the following:

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.

Builder pattern
From Wikipedia, the free encyclopedia

The builder pattern is a software design pattern. The intention is to abstract steps of
construction of objects so that different implementations of these steps can construct different
representations of objects. Often, the builder pattern is used to build products in accordance to
the composite pattern, a structural pattern.
Builder
Abstract interface for creating objects (product).
Concrete Builder
Provides implementation for Builder. It is an object able to construct other objects.
Constructs and assembles parts to build the objects.
Director
The Director class is responsible for managing the correct sequence of object creation. It
receives a Concrete Builder as a parameter and executes the necessary operations on
it.
Product
The final object that will be created by the Director using Builder.
Useful tips

 Builder focuses on constructing a complex object step by step. Abstract


Factory emphasizes a family of product objects (either simple or complex). Builder returns
the product as a final step, but as far as the Abstract Factory is concerned, the product gets
returned immediately.
 Builder often builds a Composite.
 Often, designs start out using Factory Method (less complicated, more customizable,
subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more
flexible, more complex) as the designer discovers where more flexibility is needed.
 Sometimes creational patterns are complementary: Builder can use one of the other
patterns to implement which components are built. Abstract Factory, Builder,
and Prototype can use Singletonin their implementations.

This is an implementation of the Builder pattern using inner classes in Java. The advantage
here is that the Product being built does not have to expose setters for its individual
components. This gives a better encapsulated Builder.
package builder.innerclass;

import builder.innerclass.Pizza.Builder;

class Pizza {

private String dough = "";


private String sauce = "";
private String topping = "";

public static abstract class Builder {

private Pizza pizza;

public Builder() {
pizza = new Pizza();
}

public abstract Builder buildDough();

public abstract Builder buildSauce();

public abstract Builder buildTopping();

public Pizza getPizza() {


return pizza;
}

protected void addTopping(String topping) {


pizza.topping = topping;
}
protected void addSauce(String sauce) {
pizza.sauce = sauce;
}

protected void addDough(String dough) {


pizza.dough = dough;
}
}
}

class SpicyPizzaBuilder extends Pizza.Builder {

@Override
public SpicyPizzaBuilder buildDough() {
super.addDough("Pan Baked");
return this;
}

@Override
public SpicyPizzaBuilder buildSauce() {
super.addSauce("hot");
return this;
}

@Override
public SpicyPizzaBuilder buildTopping() {
super.addTopping("pepperoni+salami");
return this;
}

class HawaiianPizzaBuilder extends Pizza.Builder {

@Override
public Builder buildDough() {
super.addDough("cross");
return this;
}

@Override
public Builder buildSauce() {
super.addSauce("mild");
return this;
}
@Override
public Builder buildTopping() {
super.addTopping("ham+pineapple");
return this;
}

class Cook {

private Pizza.Builder pizzaBuilder;

public void constructPizza() {


pizzaBuilder.buildDough().buildSauce().buildTopping();
}

public Pizza getPizza() {


return pizzaBuilder.getPizza();
}

public void setPizzaBuilder(Builder builder) {


pizzaBuilder = builder;

}
}

public class BuilderExample {

public static void main(String[] args) {


Pizza.Builder hawaiianPizzaBuilder = new
HawaiianPizzaBuilder();
Pizza.Builder spicyPizzaBuilder = new
SpicyPizzaBuilder();

Cook cook = new Cook();


cook.setPizzaBuilder(hawaiianPizzaBuilder);

cook.constructPizza();

Pizza hawaiian = cook.getPizza();

cook.setPizzaBuilder(spicyPizzaBuilder);
cook.constructPizza();
Pizza spicy = cook.getPizza();
}

Prototype pattern
From Wikipedia, the free encyclopedia

The prototype pattern is a creational design pattern used in software development when the type of objects to
create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used to:

• avoid subclasses of an object creator in the client application, like the abstract factory pattern does.

• avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it
is prohibitively expensive for a given application.

To implement the pattern, declare an abstract base class that specifies a pure virtual clone() method. Any class
that needs a "polymorphic constructor" capability derives itself from the abstract base class, and implements
the clone() operation.

The client, instead of writing code that invokes the "new" operator on a hard-coded class name, calls
the clone() method on the prototype, calls a factory method with a parameter designating the particular
concrete derived class desired, or invokes the clone() method through some mechanism provided by another
design pattern.

Adapter pattern
From Wikipedia, the free encyclopedia

In computer programming, the adapter pattern (often referred to as the wrapper pattern or simply a wrapper)
is a design pattern that translates one interface for a class into a compatible interface. An adapter allows
classes to work together that normally could not because of incompatible interfaces, by providing its interface to
clients while using the original interface. The adapter translates calls to its interface into calls to the original
interface, and the amount of code necessary to do this is typically small. The adapter is also responsible for
transforming data into appropriate forms. For instance, if multiple boolean values are stored as a single integer
but your consumer requires a 'true'/'false', the adapter would be responsible for extracting the appropriate
values from the integer value.

Intent
• Convert the interface of a class into another interface clients expect.
• Adapter lets classes work together, that could not otherwise because of incompatible
interfaces.

Implementation
The figure below shows a UML class diagram for the Adapter Pattern:

The classes/objects participating in adapter pattern:

• Target - defines the domain-specific interface that Client uses.


• Adapter - adapts the interface Adaptee to the Target interface.
• Adaptee - defines an existing interface that needs adapting.
• Client - collaborates with objects conforming to the Target interface.
Objects Adapters - Based on Delegation

Class Adapters - Based on (Multiple) Inheritance

Command pattern
From Wikipedia, the free encyclopedia

In object-oriented programming, the command pattern is a design pattern in which an object is used to
represent and encapsulate all the information needed to call a method at a later time. This information includes
the method name, the object that owns the method and values for the method parameters.

Three terms always associated with the command pattern are client, invoker and receiver.
The client instantiates the command object and provides the information required to call the method at a later
time. The invoker decides when the method should be called. The receiver is an instance of the class that
contains the method's code.

Using command objects makes it easier to construct general components that need to delegate, sequence or
execute method calls at a time of their choosing without the need to know the owner of the method or the
method parameters.

You might also like