0% found this document useful (0 votes)
123 views66 pages

Design Pattern Basics - v01

The document discusses design patterns, including their objectives, types, and features. It covers the three main types of patterns - creational, structural, and behavioral. For each type, it provides examples and descriptions of specific patterns, including singleton, factory method, and abstract factory patterns. It discusses how and when different patterns can be used to solve common object-oriented problems.

Uploaded by

SusantoPaul
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
123 views66 pages

Design Pattern Basics - v01

The document discusses design patterns, including their objectives, types, and features. It covers the three main types of patterns - creational, structural, and behavioral. For each type, it provides examples and descriptions of specific patterns, including singleton, factory method, and abstract factory patterns. It discusses how and when different patterns can be used to solve common object-oriented problems.

Uploaded by

SusantoPaul
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 66

Design Pattern Basics

Course objectives

At the completion of this course you should be able to:


Put into your own words about Design Pattern
Explain Types and Features of Design Pattern
Find more information about Creational, Structural, and Behavioral patterns
What is design pattern?

Here is the features of design pattern:


If problem occurs over and over again, a solution to that problem has been
used effectively
That solution is described as pattern
Design patterns are language independent strategies for solving common
object oriented problem
Learning design patterns is good for people to communicate effectively
Sun Suggest Gang of four (GOF) pioneer guys who wrote a book named
Design Pattern Element of reusable object oriented software
Types of design patterns

There are three types of design pattern:


Creational Patterns
Structural Patterns
Behavioral Patterns
Features of creational patterns
Below are the features of creational patterns:
These patterns focus on releasing coupling between two objects while
creating them
These reduce the coupling level by ramifying the new operator from the
components
These patterns have to do with class instantiation
Creational Patterns are of the following types:
Abstract factory
Factory Method
Builder
Prototype
Singleton
Features of structural patterns
Below are the features of structural patterns:
Ease the design by identifying a simple way to realize relationships between
entities
These are concerned with how classes and objects are composed to form larger
structure
Structural Patterns are of the following types :
Adapter
Bridge
Composite
Decorator
Faade
Flyweight
Proxy
Features of behavioral patterns

Below are the features of behavioral patterns:


These are concerned of algorithm and assignment of responsibilities between
objects
Identify common communication patterns between objects and realize the
patterns
Specifically concerned with communication between objects
Features of behavioral patterns (continued)

Behavioral patterns are of following types:


Command
Iterator
Chain of responsibility
Mediator
Observer
Strategy
State
Template Method
Visitor
Creational patterns (1 of 16)

Here is an elaborate discussion on creational patterns:


Singleton Pattern
Singleton pattern proposes that at any time there can only be one instance of a
singleton (object) created by the JVM. The classs default constructor is made
private, which prevents the direct instantiation of the object by others (Other
Classes). A static modifier is applied to the instance method that returns the object
as it then makes this method a class level method that can be accessed without
creating an object. Override the Object clone method to prevent cloning.
Steps for creating a singleton class:
Provide a default Private constructor
Create a Method for getting the reference to the Singleton Object
Make the Access method Synchronized to prevent Thread Problems.
Override the Object clone method to prevent cloning
Creational patterns (2 of 16)

An example of a Singleton class is as follows:


class SingletonClass {

private static SingletonClass singletonObject;

private SingletonClass() {
// Optional Code
}
public static synchronized SingletonClass getSingletonObject() {
if (singletonObject == null) {
singletonObject = new SingletonClass();
}
return singletonObject;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
Creational patterns (3 of 16)

Use:
Singletons can be used to create a Connection Pool object or a Logger Object.

Factory Pattern
If we have a super class and n sub-classes, and based on data provided, we
have to return the object of one of the sub-classes, we use a factory pattern.
Depending on the client input, the Factory pattern may create and return an
object which is one of the several sub-classes in consideration. But the reverse
is not always true. Any classes that creates and returns objects should not be
considered as Factory classes.
An example of Factory class is as follows :
In the example that we are looking at for explaining the Factory Design Pattern
is we are creating an object of Dog and Cat without calling the Dog or Cat class.
Creational patterns (4 of 16

Mammal Class Code:


public class MammalsFactory {
public static Mammals getMammalObject(String name) {
if (name.equalsIgnoreCase("Cat")){
return new Cat();
} else {
return new Dog();
}
}
}

Now if you see this class, here we will be passing an argument to the
getMammalObject function based on the argument passed we return the
Mammals object of the class.
Creational patterns (5 of 16)

Abstract Class Code:

public abstract class Mammals {


public abstract String doWalking();
}

Here we have created an abstract class Mammals. This class will be used by
the Dog and Cat class.
Creational patterns (6 of 16)

Cat Class Code:

public class Cat extends Mammals {


public String doWalking() {
return "Cats has been Informed to perform Walk Operation";
}
}

Here we have created Cat class, this class extends from Mammals class so it is
understandable that Cat needs to have the implementation for doWalking()
method.
Creational patterns (7 of 16)

Dog Class Code:

public class Dog extends Mammals {


public String doWalking() {
return "Dogs has been Informed to perform Walk Operation";
}
}

Here we have created Dog class, this class extends from Mammals class so it is
understandable that Dog needs to have the implementation for doWalking()
method.
Creational patterns (8 of 16)

Factory Method Client Code:


public class FactoryClient {
public static void main(String args[]) {
MammalsFactory mf = new MammalsFactory();
System.out.println(mf.getMammalObject("Dog").doWalking());
}
}

Here if you see that we want to create an object for Dog class and for that we
are not directly loading the Dog class. Instead we are instantiated the object for
MammalsFactory class.

Use:
Factory pattern is used in Data Access Object.
Creational patterns (9 of 16)

Abstract Factory Pattern:


This pattern is one level of abstraction higher than factory pattern. This means
that the abstract factory returns the factory of classes. Like Factory pattern
returned one of the several sub-classes, this returns such factory which later will
return one of the sub-classes.

Use the Abstract Factory Pattern when:


The client should be independent of how the products are created.
Application should be configured with one of multiple families of products.
Objects needs to be created as a set, in order to be compatible.
You want to provide a collection of classes and you want to reveal just their
contracts and their relationships, not their implementations.
Creational patterns (10 of 16)

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.
Creational patterns (11 of 16)

An example of an Abstract Factory class is as follows:


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() { };
}
Creational patterns (12 of 16)

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();
}
Creational patterns (13 of 16)

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();
}
Creational patterns (14 of 16)

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");
}
}
Creational patterns (15 of 16)

//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;
}
}
Creational patterns (16 of 16)

// Client
public class Client{
public static void main(String args[]){
AbstractFactory pf=FactoryMaker.getFactory("a");
AbstractProductA product=pf.createProductA();
//more function calls on product
}
}

Use:
An Abstract Factory pattern is used to create a Data Access Object.
Structural patterns (1 of 24)

Here is an elaborate discussion on structural patterns:


Adapter Pattern
Adapter pattern converts the interface of a class into another interface the
clients expect. Adapter lets classes work together that could not otherwise
because of incompatible interfaces. It converts the existing interfaces to a new
interface to achieve compatibility and reusability of the unrelated classes in one
application. There are two ways of implementing the Adapter Pattern, either use
the inheritance or use the composition.
Structural patterns (2 of 24)

Use the adapter pattern when:


You want to use an existing class, and its interface does not match the one
you need.
You want to create a reusable class that cooperates with unrelated classes
with incompatible interfaces.
(object adapter only) You need to use several existing subclasses, but it's
impractical to adapt their interface by sub classing every one. An object
adapter can adapt the interface of its parent class.
Structural patterns (3 of 24)

The following are the elements of Adapter implementation:

Target: Defines domains specific interface client uses.


Client: Collaborates with objects conforming to target interface.
Adaptee: Defines existing interface that needs adapting.
Adapter: Adapts the interface of adaptee to target interface.
Structural patterns (4 of 24)

The following example explains adapter pattern:


PrintString.java(Adaptee) :

public class PrintString {

public void print(String s)


{
System.out.println(s);
}
}

PrintableList.java(Target):
import java.util.ArrayList;

public interface PrintableList {


void printList(ArrayList<String> list);
}
Structural patterns (5 of 24)
PrintableListAdapter.java(Adapter):
import java.util.ArrayList;

public class PrintableListAdapter implements PrintableList{

public void printList(ArrayList<String> list) {

//Converting ArrayList<String> to String so that we can pass String to


// adaptee class
String listString = "";

for (String s : list)


{
listString += s + "\t";
}

// instantiating adaptee class


PrintString printString=new PrintString();
ps.print(listString);
}
}
Structural patterns (6 of 24)

AdapterDesignPatternMain.java:
import java.util.ArrayList;
public class AdapterDesignPatternMain {

public static void main(String[] args)


{
ArrayList<String> list=new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
PrintableList pl=new PrintableListAdapter();
pl.printList(list);

}
}
Structural patterns (7 of 24)

Decorator Pattern
To extend or modify the behavior of an instance at runtime decorator design
pattern is used. Inheritance is used to extend the abilities of a class. Unlike
inheritance, you can choose any single object of a class and modify its behavior
leaving the other instances unmodified. In implementing the decorator pattern
you construct a wrapper around an object by extending its behavior. The
wrapper will do its job before or after and delegate the call to the wrapped
instance. Basically, we wrap the original object through decorator object.
Decorator design pattern is based on abstract classes and we derive concrete
implementation from that classes.
Structural patterns (8 of 24)

When to Use Decorator Pattern:


To add responsibilities to individual objects dynamically without affecting other
objects
When extension by sub classing is impractical. Sometimes a large number of
independent extensions are possible and would produce an explosion of
subclasses to support every combination or a class definition may be hidden
or otherwise unavailable for sub classing
Structural patterns (9 of 24)

The following example explains decorator pattern:

// Component on Decorator design pattern

public abstract class Currency {


String description = "Unknown currency";

public String getCurrencyDescription() {


return description;
}

public abstract double cost(double value);

}
Structural patterns (10 of 24)

// Concrete Component

public class Rupee extends Currency {


double value;

public Rupee() {
description = "indian rupees";
}

public double cost(double v){


value=v;
return value;
}

}
Structural patterns (11 of 24)

//Another Concrete Component


public class Dollar extends Currency{
double value;

public Dollar () {
description = "Dollar;
}

public double cost(double v){


value=v;

return value;

}
Structural patterns (12 of 24)

// Decorator

public abstract class Decorator extends Currency{

public abstract String getDescription();

}
Structural patterns (13 of 24)

// Concrete Decorator
public class USDDecorator extends Decorator{

Currency currency;

public USDDecorator(Currency currency){


this.currency = currency;
}

public String getDescription(){


return currency.getDescription()+" ,its US Dollar";
}

}
Structural patterns (14 of 24)

//Another Concrete Decorator

public class SGDDecorator extends Decorator{


Currency currency;

public SGDDecorator(Currency currency){


this.currency = currency;
}

public String getDescription(){


return currency.getDescription()+" ,its singapore Dollar";
}

}
Structural patterns (15 of 24)

//check currency
public class CurrencyCheck {

public static void main(String[] args) {

// without adding decorators

Currency curr = new Dollar();

System.out.println(curr.getDescription() +" dollar. "+curr.cost(2.0));

//adding decorators

Currency curr2 = new USDDecorator(new Dollar());

System.out.println(curr2.getDescription() +" dollar. "+curr2.cost(4.0));

Currency curr3 = new SGDDecorator(new Dollar());

System.out.println(curr3.getDescription() +" dollar. "+curr3.cost(4.0));


}
Structural patterns (16 of 24)

Bridge Pattern
The intent for bridge design pattern is to decouple an abstraction from its
implementation so that the two can vary independently. In the bridge pattern, we
separate an abstraction and its implementation and develop separate
inheritance structures for both the abstraction and the implementor. The
abstraction is an interface or abstract class, and the implementor is likewise an
interface or abstract class. The abstraction contains a reference to the
implementor. Children of the abstraction are referred to as refined abstractions,
and children of the implementor are concrete implementors. Since we can
change the reference to the implementor in the abstraction, we are able to
change the abstraction's implementor at runtime. Changes to the implementor
do not affect client code.
Structural patterns (17 of 24)

The main components of a Bridge decorator pattern are:


Abstraction
defines the abstract interface
maintains the Implementor reference

Refined Abstraction
extends the interface defined by Abstraction

Implementor
defines the interface for implementation classes

ConcreteImplementor
implements the Implementor interface
Structural patterns (18 of 24)

Use Decorator pattern when:


You want to separate abstraction and implementation permanently
Share an implementation among multiple objects
Want to improve extensibility
Hide implementation details from clients
Structural patterns (19 of 24)

The following example explains Bridge Pattern:

Shape.java(Abstraction):

Public abstract class Shape {

Color color;
Shape(Color color)
{
this.color=color;
}
abstract public void colorIt();
}
Structural patterns (20 of 24)

Rectangle.java(RefinedAbstraction):

public class Rectangle extends Shape{

Rectangle(Color color) {
super(color);
}

public void colorIt() {


System.out.print("Rectangle filled with ");
color.fillColor();
}
}
Structural patterns (21 of 24)

Circle.java(RefinedAbstraction):

public class Circle extends Shape{

Circle(Color color) {
super(color);
}

public void colorIt() {


System.out.print("Circle filled with ");
color.fillColor();
}
}
Structural patterns (22 of 24)

Color.java(Implementor):

public interface Color {

public void fillColor();


}

RedColor.java(ConcreteImplementor):

public class RedColor implements Color{

public void fillColor() {


System.out.println("red color");
}
}
Structural patterns (23 of 24)

BlueColor.java(ConcreteImplementor):

class BlueColor implements Color{

public void fillColor() {


System.out.println("blue color");
}
}
Structural patterns (24 of 24)

BridgeDesignPatternMain.java:

public class BridgeDesignPatternMain {

public static void main(String[] args) {

Shape s1=new Rectangle(new RedColor());


s1.colorIt();
Shape s2=new Circle(new BlueColor());
s2.colorIt();
}
}
Behavioral patterns (1 of 15)
Here is an elaborate discussion on behavioral patterns:
Command Pattern
Command design pattern is used to encapsulate a request as an object and pass to an
invoker, wherein the invoker does not know how to service the request but uses the
encapsulated command to perform an action.
To understand command design pattern we should understand the associated key terms
like client, command, command implementation, invoker, and receiver.
Command is an interface with execute method. It is the core of contract.
A client creates an instance of a command implementation and associates it with a
receiver.
An invoker instructs the command to perform an action.
A Command implementations instance creates a binding between the receiver and an
action.
Receiver is the object that knows the actual steps to perform the action.
Behavioral patterns (2 of 15)

The important features of Command Pattern are as follows:


Command pattern helps to decouple the invoker and the receiver. Receiver is
the one, which knows how to perform an action.
Command helps to implement call back in java.
Helps in terms of extensibility as we can add new command without changing
existing code.
Command defines the binding between receiver and action.
A command should be able to implement undo and redo operations. That is
resting the state of the receiver. It can be done from the support of receiver.
Behavioral patterns (3 of 15)

The Command Pattern is useful when:


A history of requests is needed
You need callback functionality
Requests need to be handled at variant times or in variant orders
The invoker should be decoupled from the object handling the invocation

The following example explains command pattern:

//Command Interface
public interface Command
{
public void execute();
}
Behavioral patterns (4 of 15)

//Concrete Command
public class LightOnCommand implementsCommand
{
//reference to the light
Light light;

public LightOnCommand(Light light)


{
this.light = light;
}

public void execute()


{
light.switchOn();
}

}
Behavioral patterns (5 of 15)

//Concrete Command
public class LightOffCommand implementsCommand
{
//reference to the light
Light light;

public LightOffCommand(Light light)


{
this.light = light;
}

public void execute()


{
light.switchOff();
}

}
Behavioral patterns (6 of 15)

//Receiver
public class Light
{
private boolean on;

public void switchOn()


{
on = true;
}

public void switchOff()


{
on = false;
}

}
Behavioral patterns (7 of 15)

//Invoker
public class RemoteControl
{
private Command command;

public void setCommand(Command command)


{
this.command = command;
}

public void pressButton()


{
command.execute();
}

}
Behavioral patterns (8 of 15)
//Client
public class Client
{
public static void main(String[] args)
{
RemoteControl control = new RemoteControl();

Light light = new Light();

Command lightsOn = new LightsOnCommand(light);


Command lightsOff = new LightsOffCommand(light);

//switch on
control.setCommand(lightsOn);
control.pressButton();

//switch off
control.setCommand(lightsOff);
control.pressButton();

}
Behavioral patterns (9 of 15)

Iterator Pattern
Iterator pattern provides a way to access the elements of an aggregate object
without exposing its underlying representation. The iterator pattern allows for the
traversal through the elements in a grouping of objects via a standardized
interface. An Iterator interface defines the actions that can be performed. These
actions include being able to traverse the objects and also obtain the objects.
This is widely used java.util.Iterator interface which is used to iterate through
things such as Java collections. We can write our own iterator by implementing
java.util.Iterator. This interface features the hasNext(), next(), and remove()
methods. When writing an iterator for a class, it is very common for the iterator
class to be an inner class of the class that we'd like to iterate through.
Behavioral patterns (10 of 15)

Use Iterator pattern when:


You need access to elements in a set without access to the entire
representation. Iterator is a good choice when you need a uniform traversal
interface, and multiple traversals may happen across elements.
Behavioral patterns (11 of 15)

The following code explains Iterator pattern:

public static void main(String args[]){

List<String> list = new ArrayList<String>();


//add strings
list.add(cricket);
list.add(football);
list.add(hockey);

Iterator it = list.iterator();
while(it.hasNext())
{
String s = it.next();
}

}
Behavioral patterns (12 of 15)

Observer Pattern
Observer Pattern defines a one-to-many dependency between objects so that
when one object changes state, all its dependents are notified and updated
automatically. The object, which is being watched is called the subject. The
objects, which are watching the state changes are called observers or listeners.

When this pattern is useful:


In general, you want to use this pattern to reduce coupling. If you have an object
that needs to share its state with others, without knowing who those objects are,
the observer is exactly what you need.
Behavioral patterns (13 of 15)
The following code explains Observer pattern:
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.
public class DataStore extends Observable
{
private String data;
public String getData()
{
return data;
}

public void setData(String data)


{
this.data =data;
//mark the observable as changed
setChanged();
}
}
Behavioral patterns (14 of 15)

We have called the setChanged() method of the Observable. This is necessary


in order for the call to notify observers to send out the update. Without this set,
the Observable will see no reason to send out the update.
Next, let us create our Observer. To do this, all we need to do is implement the
Observer interface which forces us to write an update method, to deal with
changes in the Observable's state.

public class Screen implements Observer {

@Override
public void update(Observable o, Object arg) {

//act on the update


}

}
Behavioral patterns (15 of 15)

Adding our Screen as an observer to the DataStore is as follows:


Screen screen = new Screen();

DataStore dataStore = new DataStore();


//register observer
dataStore.addObserver(screen);

When the data changes, we want to notify all observers of this object. To do
this, we just need to call the notifyObservers method when we want an update
sent out

//send a notification
dataStore.notifyObservers();
Course summary

Having completed this course you should now be able to:


Put into your own words about Design Pattern
Explain Types and Features of Design Pattern
Find more information about Creational, Structural, and Behavioral patterns

You might also like