Sitemap

Java Design Patterns 2021

12 min readFeb 13, 2021

--

Press enter or click to view image in full size
Photo by Jeremy Bishop on Unsplash

Design patterns are best practices to general problems that software developers faced during software development. Design patterns are primarily based on object orientated design principles of,

  • Program to an interface not an implementation
  • Favor object composition over inheritance

Types of Design Patterns

  • Creational —hides the object creation logic
  • Structural — focus on class and object composition
  • Behavioral — focus on communication between objects.
  • J2EE — focus on presentation tier

Factory Pattern

Create the object without exposing the creation logic and access the object using a common interface.

      ShapeFactory shapeFactory = new ShapeFactory();
Shape shape1 = shapeFactory.getShape("CIRCLE");
Shape shape2 = shapeFactory.getShape("RECTANGLE");

In this example shapefactory creates the required shape based on the parameter passed in. Inside the shapefactory it has the normal shape creation logic. Shape is an interface used by other objects.

Abstract Factory Pattern

Patterns creates other factories acts like factory of factories.

      AbstractFactory shapeFactory =     FactoryProducer.getFactory("rounded");
Shape shape1 = shapeFactory.getShape("RECTANGLE");
Shape shape2 = shapeFactory.getShape("SQUARE");
//get boxed shape factory
AbstractFactory shapeFactory1 = FactoryProducer.getFactory("boxed");
Shape shape3 = shapeFactory1.getShape("RECTANGLE");
Shape shape4 = shapeFactory1.getShape("SQUARE");

shape 1 & 2 has rounded corners and 3 & 4 has boxed corners.

Singleton Pattern

This patterns allows creating only a single object. This is achieved by limiting access to object via class only.

public class SingleObject {
private static SingleObject instance = new SingleObject();

//make the constructor private - not to instantiated
private SingleObject(){}

//make static - can access class method directly
public static SingleObject getInstance(){
return instance;
}
}

This object can be accessed via getInstance() only.

Press enter or click to view image in full size
Photo by Karsten Winegeart on Unsplash

Builder Pattern

We will use builder pattern instead of factory pattern when the object creation is complex.

MealBuilder mealBuilder= new MealBuilder();
Meal vegMeal = mealBuilder.addVegBurger()
.addCoke()
.build()

when we execute build() it may use few other objects to create the meal object as bellow.

private vegBurger, coke;
MealBuilder addVegBurger(){
vegBurger=new vegBurger()
return this;
}
MealBuilder addCoke(){
coke=new coke()
return this;
}
Meal build(){
Meal meal=new Meal();
meal.setVegBurger(this.vegBurger);
meal.setCoke(this.coke);
}

Prototype Pattern

Is the creation of object using existing objects when object creation is time consuming, and costly.

Shape clonedShape = (Shape) ShapeCache.getShape("1");
Shape clonedShape2 = (Shape) ShapeCache.getShape("2");

getShape will be returning a cloned object

public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape) cachedShape.clone();
}

shapeMap is created like this

      Circle circle = new Circle();
circle.setId("1");
shapeMap.put(circle.getId(),circle);
...
shapeMap.put(square.getId(),square);
shapeMap.put(rectangle.getId(), rectangle);

Ref: https://www.tutorialspoint.com/design_pattern/prototype_pattern.htm

Adapter Pattern

works as a bridge between two incompatible interfaces. It’s like a card reader acts as an adapter between memory card and a laptop.

class Sparrow { 
public void makeSound() { println("Chirp Chirp"); }
}
class ToyDuck {
public void squeak() { println("Squeak")}
}

what if sparrow wants to squeak?

Sparrow sparrow = new Sparrow();
ToyDuck sparrowAsDuck = new BirdAdapter(sparrow);
sparrowAsDuck.squeak();

BirdAdapter class may have a method like this

     public void squeak() { 
Sparrow.makeSound();
}

Basically methods are matched at adapter class. https://www.geeksforgeeks.org/adapter-pattern/

Bridge Pattern*

This pattern involves an interface which acts as a bridge which makes the functionality of concrete classes independent from interface implementer classes. Both types of classes can be altered structurally without affecting each other.

The display of different image formats on different operating systems is a good example of the Bridge pattern. The image structure is the same across all operating systems, but the how it’s viewed (the implementation) is different on each OS.

public interface TV{ 
public void on();}
public class Sony implements TV{
public void on(){//Sony specific on}}
public class Philips implements TV{
public void on(){//Philips specific on}}
public abstract class RemoteControl{
private TV implementor;
public void on() { implementor.on(); }
}

Now we have a pretty standard remote control. And what if we need a picture in picture feature in the remote control.

public class ConcreteRemote extends RemoteControl{
public void pip() {
//pip implementation
}
}

In this example tv features will involve separately and remote control separately too as both has too separate interfaces.

Ref: https://dzone.com/articles/design-patterns-bridge

Filter/Criteria Pattern

enables to filter a set of objects using different criteria and chaining them in a decoupled way through logical operations.

persons.add(new Person("Robert","Male", "Single"));
persons.add(new Person("John", "Male", "Married"));
Criteria singleMale = new AndCriteria(single, male);
singleMale.meetCriteria(persons)

https://www.tutorialspoint.com/design_pattern/filter_pattern.htm

Composite Pattern

is used where we need to treat a group of objects like a single object.

Employee CEO = new Employee("John","CEO", 30000);Employee headSales = new Employee("Robert","Head Sales", 20000);CEO.add(headSales);

May be we can print all child objects by looping through all the childrens of ceo object

for (Employee headEmployee : CEO.getSubordinates()) {
System.out.println(headEmployee);

Decorator Pattern

Allow adding new functionality to an existing object without altering its structure.

Shape circle = new Circle();Shape redCircle = new RedShapeDecorator(new Circle());

Facade Pattern

hides the complexities of the system and provides an interface to access.

ShapeMaker shapeMaker = new ShapeMaker();
shapeMaker.drawCircle();
shapeMaker.drawRectangle();

ShapeMaker is the facade class has following implementation

Shape circle = new Circle();
Shape rectangle = new Rectangle();
public void drawCircle(){
circle.draw();
}
public void drawRectangle(){
rectangle.draw();
}
Press enter or click to view image in full size
Photo by Frame Harirak on Unsplash

Flyweight Pattern

Flyweight pattern tries to reuse already existing objects by storing them. to reduce the number of objects created and to decrease memory footprint and increase performance.

public class ShapeFactory {


private static final HashMap circleMap = new HashMap();

public static Shape getCircle(String color) {
Circle circle = (Circle)circleMap.get(color);

if(circle == null) {
circle = new Circle(color);
circleMap.put(color, circle);
}
return circle;
}
}

Whenever a request comes it checks the circle object in its HashMap before creating a new one.

Proxy Pattern

a class represents functionality of another class to outer world.

class ProxyImage {
private RealImage realImage;
public void display() {
if(realImage == null){
realImage = new RealImage();
}
realImage.display();
}
}

Creates the real image only if its not creates before

Chain of Responsibility Pattern

each receiver contains reference to another receiver. creates a chain of receiver objects for a request. decouples sender and receiver of a request based on type of request.

AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO,"info.");

getChainOfLoggers() will create objects will link them via setNextLogger()

private static AbstractLogger getChainOfLoggers(){

AbstractLogger error = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger file = new FileLogger(AbstractLogger.DEBUG);

error.setNextLogger(file);


return error;
}

When logMessage() is called will write the message and if next logger is available it also will be invoked.

public void logMessage(int level, String message){
if(this.level <= level){
write(message);
}
if(nextLogger !=null){
nextLogger.logMessage(level, message);
}
}

https://www.tutorialspoint.com/design_pattern/chain_of_responsibility_pattern.htm

Command Pattern

A request is wrapped under an object as command and passed to invoker object. Invoker object looks for the appropriate object which can handle this command.

      Stock abcStock = new Stock();

BuyStock buyStockOrder = new BuyStock(abcStock);
SellStock sellStockOrder = new SellStock(abcStock);

Broker broker = new Broker();
broker.takeOrder(buyStockOrder);
broker.takeOrder(sellStockOrder);

broker.placeOrders();

placeOrder() of the Broker class invokes execute()

public void placeOrders(){   
for (Order order : orderList) {
order.execute();
}
}

execute() will be buy or sell based on the class

public class SellStock implements Order {
private Stock abcStock;
public void execute() {
abcStock.sell();
}
}
public class BuyStock implements Order {
private Stock abcStock;
public void execute() {
abcStock.buy();
}
}

https://www.tutorialspoint.com/design_pattern/command_pattern.htm

Interpreter Pattern

provides a way to evaluate language grammar or expression. This involves implementing an expression interface which tells to interpret a particular context. This is used in SQL parsing, symbol processing engine etc.

//Rule: Julie is a married women


public static Expression getMarriedWomanExpression(){
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married");
return new AndExpression(julie, married);
}

Check the rule

Expression isMarriedWoman = getMarriedWomanExpression();
System.out.println("Julie is a married women? " + isMarriedWoman.interpret("Married Julie"));

AndExpression.interpret() will return true if text in the rule objects is in the message we verify

Ref: https://www.tutorialspoint.com/design_pattern/interpreter_pattern.htm

Press enter or click to view image in full size
Photo by Pascal Brokmeier on Unsplash

Iterator Pattern

Can access the elements of a collection object in sequential manner without knowing its underlying representation.

      for(Iterator iter = sample.getIterator(); iter.hasNext();){
String name = (String)iter.next();
System.out.println("Name : " + name);
}

hasNext() and next() can be implemented like this

public String names[] = {"Robert" , "John" ,"Julie" , "Lora"};public boolean hasNext() {      
if(index < names.length){
return true;
}
return false;
}
public Object next() {
if(this.hasNext()){
return names[index++];
}
return null;
}

https://www.tutorialspoint.com/design_pattern/iterator_pattern.htm

Mediator Pattern

Reduces communication complexity between multiple objects or classes. A mediator class will handle all the communications. supports easy maintenance of the code by loose coupling. Ex: chat room

User john = new User("John");
robert.sendMessage("Hi! John!");

users send message to chat room where user object will act as mediator object.

public void sendMessage(String message){
ChatRoom.showMessage(this,message);
}

chat room to show the messages to all users

   public static void showMessage(User user, String message){
System.out.println( message);
}

Memento Pattern

to restore state of an object to a previous state.

It has three actor classes Memento contains state of an object to be restored. Originator creates and stores states in Memento objects and Caretaker object is responsible to restore object state from Memento.

     originator.setState("State #1");
careTaker.add(originator.saveStateToMemento());
originator.getStateFromMemento(careTaker.get(0));

Observer Pattern

To communicate to dependents when there is one-to-many relationship between objects. Observer pattern uses three actor classes. Subject, Observer and Client. Subject is an object having methods to attach and detach observers to a client object.

Subject subject = new Subject();
new HexaObserver(subject);

subject class is created and observer class is extended to HexaObserver.

public class HexaObserver extends Observer{
protected Subject subject;
public HexaObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}}

now subject is attached to HexaObserver object internally.

Get Nuwan Zen’s stories in your inbox

Join Medium for free to get updates from this writer.

https://www.tutorialspoint.com/design_pattern/observer_pattern.htm

State Pattern

class behavior changes based on its state.

Context context = new Context();

StartState startState = new StartState();
startState.doAction(context);



StopState stopState = new StopState();
stopState.doAction(context);

we can change the state of the context based on the object its been passed. This method resides in StartState and StopState classes.

public void doAction(Context context) {
context.setState(this);
}

https://www.tutorialspoint.com/design_pattern/state_pattern.htm

Null Object Pattern

a null object replaces check of NULL object instance. provide default behaviour in case data is not available.

public static AbstractCustomer getCustomer(String name){     
if (names.equalsIgnoreCase(name)){
return new RealCustomer(name);
}
return new NullCustomer();
}

null customer could be

public class NullCustomer{
public String getName() {
return "Not Available in Customer Database";
}
public boolean isNil() {
return true;
}
}

https://www.tutorialspoint.com/design_pattern/null_object_pattern.htm

Strategy Pattern

a class behavior can be changed at run time.

Context context = new Context(new OperationAdd());		
context.executeStrategy(10, 5);

context = new Context(new OperationMultiply());
context.executeStrategy(10, 5);

Context class

   public Context(Strategy strategy){
this.strategy = strategy;
}

public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}

behavior is copied from the passed in parameter, implementation of doOperation will be coming from OperationAdd or OperationMultiply classes.

https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm

Template Pattern

an abstract class exposes defines templates for subclass methods.

public abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();

//template method
public final void play(){

//initialize the game
initialize();

//start game
startPlay();

//end game
endPlay();
}
}

when cricket class is inhertited from game class it will follow the template provided. note the final contructor in Game class.

Game game = new Cricket();
game.play();

https://www.tutorialspoint.com/design_pattern/template_pattern.htm

Visitor Pattern*

In Visitor pattern, we use a visitor class which changes the executing algorithm of an element class. By this way, execution algorithm of element can vary as and when visitor varies. element object has to accept the visitor object so that visitor object handles the operation on the element object.

computer.accept(new Visitor());

Computer

public void accept(Visitor visitor) {

mouse.accept(visitor);

visitor.visit(this);
}

Visitor

public void visit(Mouse mouse) {
System.out.println("Displaying Mouse.");
}
public void visit(Computer computer) {
System.out.println("Displaying Computer.");
}

Mouse

public void accept(Visitor visitor) {
visitor.visit(this);
}

https://www.tutorialspoint.com/design_pattern/visitor_pattern.htm

MVC Pattern

separate application’s concerns to

  • Model — object or JAVA POJO carrying data. It can also have logic to update controller if its data changes.
  • View — visualization of the data that model contains.
  • Controller — Controller acts on both model and view. It controls the data flow into model object and updates the view whenever data changes. It keeps view and model separate.
Student model  = new Student();
StudentView view = new StudentView();

StudentController controller = new StudentController(model, view);
controller.updateView();

StudentController

public void updateView(){				
view.printStudentDetails(model.getName(), model.getRollNo());
}

updateview method will call the view object to print the data.

https://www.tutorialspoint.com/design_pattern/mvc_pattern.htm

Business Delegate Pattern

Decouples presentation tier and business tier.

  • Client — Presentation tier code may be JSP, servlet or UI java code.
  • Business Delegate — entry point to access Business Service methods.
  • LookUp Service —get relative business implementation and provide business object access to business delegate object.
  • Business Service — provide actual business implementation logic.
BusinessDelegate businessDelegate = new BusinessDelegate();
Client client = new Client(businessDelegate);
businessDelegate.setServiceType("EJB");
client.doTask();

businessDelegate.setServiceType("JMS");
client.doTask();

doTask method, this will call the print method of the returned object.

businessService = lookupService.getBusinessService(serviceType);
businessService.print();

getBusinessService will return object based on input type

if(serviceType.equalsIgnoreCase("EJB")){
return new EJBService();
}
else {
return new JMSService();
}

client > delegate > lookup > service

https://www.tutorialspoint.com/design_pattern/business_delegate_pattern.htm

Composite Entity Pattern*

Composite Entity pattern is used in EJB persistence mechanism. A Composite entity is an EJB entity bean which represents a graph of objects. When a composite entity is updated, internally dependent objects beans get updated automatically as being managed by EJB entity bean.

Client client = new Client();
client.setData("Test", "Data");
client.printData();

class Client

public void printData(){
print( compositeEntity.getData());
}

public void setData(String data1, String data2){
compositeEntity.setData(data1, data2);
}

class CompositeEntity

public void setData(String data1, String data2){
CoarseGrainedObject.setData(data1, data2);
}

public String[] getData(){
return CoarseGrainedObject.getData();
}

https://www.tutorialspoint.com/design_pattern/composite_entity_pattern.htm

Data Access Object Pattern

DAO pattern is used to separate low level data accessing API or operations from high level business services. participants

  • Data Access Object Interface — defines the standard operations to be performed on a model object(s).
  • Data Access Object concrete class — implements above interface. responsible to get data from a data source
  • Model Object or Value Object — simple POJO containing get/set methods to store data retrieved using DAO class.
StudentDao studentDao = new StudentDaoImpl();

Student student =studentDao.getAllStudents().get(0);
student.setName("Michael");
studentDao.updateStudent(student);

class StudentDaoImpl

public List<Student> getAllStudents() {
return students;
}
public void updateStudent(Student student) {
students.get(student.getRollNo()).setName(student.getName());

}

class Student

public void setName(String name) {
this.name = name;
}

https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm

Front Controller Pattern

provide a centralized request handling mechanism so that all requests will be handled by a single handler. This handler can do the authentication/ authorization/ logging or tracking of request and then pass the requests to corresponding handlers. entities,

  • Front Controller — Single handler for all kinds of requests coming to the application (either web based/ desktop based).
  • Dispatcher — dispatch the request to corresponding specific handler.
  • View — Views are the object for which the requests are made.
FrontController frontController = new FrontController();
frontController.dispatchRequest("HOME");
frontController.dispatchRequest("STUDENT");

class FrontController

dispatcher = new Dispatcher();public void dispatchRequest(String request){ 
if(isAuthenticUser()){
dispatcher.dispatch(request);
}
}

class Dispatcher

studentView = new StudentView();
homeView = new HomeView();
public void dispatch(String request){
if(request.equalsIgnoreCase("STUDENT")){
studentView.show();
}
else{
homeView.show();
}
}

https://www.tutorialspoint.com/design_pattern/front_controller_pattern.htm

Press enter or click to view image in full size
Photo by XPS on Unsplash

Intercepting Filter Pattern

to do some pre-processing / post-processing. Filters can do the authentication/ authorization/ logging or tracking of request and then pass the requests to corresponding handlers.

  • Filter — performs task prior or after execution of request handler.
  • Filter Chain —carries multiple filters and execute in order.
  • Target — request handler
  • Filter Manager — manages the filters and Filter Chain.
  • Client — sends request to the Target object.
FilterManager filterManager = new FilterManager(new Target());
filterManager.setFilter(new AuthenticationFilter());
filterManager.setFilter(new DebugFilter());

Client client = new Client();
client.setFilterManager(filterManager);
client.sendRequest("HOME");

class Client

public void sendRequest(String request){
filterManager.filterRequest(request);
}

class FilterManager

filterChain.setTarget(target);
public void filterRequest(String request){
filterChain.execute(request);
}

class FilterChain

public void execute(String request){
for (Filter filter : filters) {
filter.execute(request);
}
target.execute(request);
}

https://www.tutorialspoint.com/design_pattern/intercepting_filter_pattern.htm

Service Locator Pattern

To locate services using JNDI lookup. Caches the service object for performance.

  • Service — Actual Service which will process the request. Reference of such service is to be looked upon in JNDI server.
  • Context / Initial Context — JNDI Context carries the reference to service used for lookup purpose.
  • Service Locator — Service Locator is a single point of contact to get services by JNDI lookup caching the services.
  • Cache — Cache to store references of services to reuse them
  • Client — Client is the object that invokes the services via ServiceLocator.
Service service = ServiceLocator.getService("Service1");
service.execute();

class ServiceLocator

private static Cache cache;

static {
cache = new Cache();
}

public static Service getService(String jndiName){

Service service = cache.getService(jndiName);

if(service != null){
return service;
}

InitialContext context = new InitialContext();
Service service1 = (Service)context.lookup(jndiName);
cache.addService(service1);
return service1;
}

InitialContext will return service object based on jndi name, cache will store that object in a list.

https://www.tutorialspoint.com/design_pattern/service_locator_pattern.htm

Transfer Object Pattern

To pass data with multiple attributes in one shot from client to server. Transfer Object is a simple POJO class having getter/setter methods and is serializable so that it can be transferred over the network.

StudentBO s = new StudentBO();      //update student
StudentVO student = s.getAllStudents().get(0);
student.setName("Michael");
s.updateStudent(student);

class StudentBO is the Business Object.

List<StudentVO> students;public void updateStudent(StudentVO student) {
students.get(student.getRollNo()).setName(student.getName());
}
public List<StudentVO> getAllStudents() {
return students;
}

StudentVO is the Transfer Object. its a pojo class.

https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm

Read my other blogs:

--

--

Written by Nuwan Zen

Sometimes A software Engineer, sometimes a support engineer, sometimes a devops engineer, sometimes a cloud engineer :D That’s how the this life goes!