Skip to main content

Behavioural Patterns

Template Method Pattern

The template method pattern is a behavioural pattern. And as the name itself says it provides a base template method. When we are working with inheritance in our applications we provide a base template method that should be used by the child classes. The child classes can override certain methods but they should use the base template method as is.

For example we have a data renderer class which can read the data, process the data and then render or display that data to the end user.But in our application we want to render the data in the same way no matter in which format the data is coming in that is if it is xml data or if it is CSV data. We want to render it using the render method in the base class reading the data and processing that data is up to the child classes. The child classes can override the readData and the processData.But we want to provide a base template method with all the implementation in it in that data renderer superclass. This pattern is called template method ,as we are providing a template for a particular method from the parent class that should be used by the child classes.

package templatemethod;

public abstract class ComputerManufacturerAbstract {
public void buildComputer(){
addHardDisk();
addKeyboard();
addRam();
}

abstract void addHardDisk();
abstract void addRam();
abstract void addKeyboard();
}
-----

package templatemethod;

public class DestopManufacturer extends ComputerManufacturerAbstract{


@Override
void addHardDisk() {
System.out.println("desktop hardDisk created");
}

@Override
void addRam() {
System.out.println("desktop ram created");
}

@Override
void addKeyboard() {
System.out.println("desktop keyboard created");
}
}

------
package templatemethod;

public class LaptopManufacturer extends ComputerManufacturerAbstract {
@Override
void addHardDisk() {
System.out.println("laptop hardDisk created");
}

@Override
void addRam() {
System.out.println("laptop ram created");
}

@Override
void addKeyboard() {
System.out.println("laptop keyboard created");
}
}

------
package templatemethod;

public class Test {
public static void main(String[] arg){
ComputerManufacturerAbstract cma = new LaptopManufacturer();
cma.buildComputer();
}
}

Adapter Pattern

If you have used a power adapter then you already know what an adapter pattern is .The job of a power adapter is to adapt it to a particular location and a particular switchboard.For example the same laptop plug pins that work in USA will not work in UK and in India.We will have to use appropriate power adapter that can take our laptop pins into it and on the other side of it it will have pins that can go into the local countries switchboard and it can also adapt to the appropriate range in that country. Similarly in the world of programming when we have two applications communicating with each other or two objects using each other and one object invokes the method of another object.Then we have to adapt in some cases.

For example here we have a WeatherFinder class which has a findWeather. By passing in a city you can get the weather and we have an implementation of it which will return the weather back and there is a UI class that wants to use the weather finder . But the UI only knows the zip code of the city. It does not have the city information it only has the zip code but it wants to get the weather of it.

That is where an adapter comes in. We will implement an adapter which will take the zip code. The weather UI will invoke the findTemperature Method on the WeatherAdapter it will pass in the zip code. The weather adapter is responsible for looking up for the appropriate city that matches the zip code and hen invoke the weather finder, take the results and return the results back to the weather UI. So it exactly acts like a power adapter. It takes the inputs from the class that wants to use another class because the inputs here are different from what the other side of the relationship expects.

package com.sudhir.patterns.adapter;

public class WeatherFinderImpl implements WeatherFinder {

@Override
public int find(String city) {
return 33;
}

}

-----

package com.sudhir.patterns.adapter;

public interface WeatherFinder {

int find(String city);

}

-----
package com.sudhir.patterns.adapter;

public class WeatherAdapter {

public int findTemperature(int zipCode) {
String city = null;
if (zipCode == 19406) {
city = "King Of Prussia";
}
WeatherFinder finder = new WeatherFinderImpl();
int temperature = finder.find(city);

return temperature;

}

}
-----
package com.sudhir.patterns.adapter;

public class WeatherUI {

public void showTemperature(int zipcode) {
WeatherAdapter adapter = new WeatherAdapter();
System.out.println(adapter.findTemperature(zipcode));

}

public static void main(String[] args) {
WeatherUI ui = new WeatherUI();
ui.showTemperature(19406);
}

}

Command Pattern

A command design pattern is a behavioural design pattern from that gang of four patterns. It is used to encapsulate a request as an object and pass it to an invoker the invoker do not know how to service the request from the client. It will take the command and pass it to a receiver who knows how to perform the action typically.

There are five actors in the command design pattern. They are the command itself. The client the invoker the concrete command that implements the command and a receiver who knows how to perform all the actions. Let's take a look at an example to see all these five actors in action. Let's consider a person who is using a television or is watching a television and he uses a remote control typically to perform several operations. But let's simply take the on and off operations and let's see how the command pattern fits in here.Here the person is the client who wants to execute the on and off command on it television, the remote control is the invoker so he uses remote control to invoke a particular command by pressing a button and the commands themselves are the on command and off command that implement a interface called Command which has a execute method.

So the person will wrap this on command passes it to the remote control the remote control will send that command to the television and the television knows how to perform that action based on the command that comes in when it is on.

It will execute the command which is passed in which is the on command execute method. And when it is off it will perform the Execute method of the off command to switch off the television.

Here person is the client remote control is the Invoker command is the command interface on command and off command are the concrete command classes. And finally television is the receiver who knows how to perform the action. The huge advantage of the command pattern is that the invoker which is the client and the remote control are completely decoupled from the receiver.

The person need not touch the television or he need not know how to perform the on and off command he simply uses the remote control and presses the button the remote control also doesn't care how the actions are performed. It simply passes the command to the television. That way they are completely decoupled the invoker does not know the details of the action that needs to be performed. The receiver here the television can change the implementation of how the on and off should be performed without impacting the remote control and the person.

package command;

public interface Command {
public void execute();
}
-----

package command;

public class OffCommand implements Command {
Television tel;

public OffCommand(Television tel){
this.tel = tel;
}
@Override
public void execute() {
tel.off();
}
}

----

package command;

public class OnCommand implements Command {
Television tel;

public OnCommand(Television tel){
this.tel = tel;
}
@Override
public void execute() {
tel.on();
}
}

-----
package command;

public class Person {

public static void main(String[] args) {
Television tel = new Television();
RemoteControl rc = new RemoteControl();

OnCommand oc = new OnCommand(tel);
rc.setCommand(oc);
rc.pressButton();

OffCommand ofc = new OffCommand(tel);
rc.setCommand(ofc);
rc.pressButton();
}
}

----

package command;

//Invoker of the command
public class RemoteControl {

private Command command;

public void pressButton(){
command.execute();
}

public Command getCommand() {
return command;
}

public void setCommand(Command command) {
this.command = command;
}


}
-----
package command;

//Receiver
public class Television {
public void on(){
System.out.println("Television is switched ON");
}

public void off(){
System.out.println("Television is switched OFF");
}
}

Decorator Pattern

A decorator pattern is a behavioural pattern that adds additional functionality to an object dynamically at runtime. A decorator wraps an object with additional behaviour without affecting other objects of the same type. The classes in the input output streams in Java use the decorator pattern to read and write files.

For example lets consider a pizza shop. We have a pizza and we have a base pizza. A plain pizza, pizza by itself doesn't mean anything it is very abstract. A plain pizza probably it is just the dove without any cheese or veggies or any meat on it. And now when the client wants a plain pizza or he can ask for a veggie pizza or a cheese pizza or meat pizza

At runtime we can dynamically add all these toppings using a pizza decorator as required. A pizza decorator will be implemented by veggie pizza decorator and a cheese pizza decorator. Each of these bring in additional functionality. So if the client asks for a veggie pizza we are going to use the veggie pizza decorator at run time.

The client ask for a cheese pizza. We can ask the cheese pizza decorator to decorate the plain base pizza with cheese and with veggies as required. The pizza here is the component the plain pizza is a concrete or a base component. The decorator is the pizza decorator and these two are concrete decorators. Both the veggie pizza decorator and the cheese pizza decorator are called concrete decorators so you are going to implement all of that in the next few lectures.


Iterator Pattern