Strategy Design Pattern in Java

This article explains strategy design pattern in Java with class diagrams and example code.

Introduction – Strategy Design Pattern is a behavioral design pattern among the Gang Of Four(GOF) Design PatternsArticle on GOF Patterns & their types. I.e. the strategy design pattern deals with how the classes interact with each other.

What is Strategy Design Pattern
Strategy Pattern is used when there is a family of interchangeable algorithms of which one algorithm is to be used depending on the program execution context.
Strategy Pattern achieves this by clearly defining the family of algorithms, encapsulating each one and finally making them interchangeable. Each of the algorithms in the family can vary independently from the clients that use it.
Interchangeability is achieved by making a parent interface/base strategy class and keeping individual algorithms as children of this base class. The client class holds a reference to the base strategy and at runtime receives the correct algorithm child instance depending on the execution context.

Lets have a look at the class diagram of the strategy pattern –

Strategy Design Pattern Class Diagram

Strategy Design Pattern Class Diagram

Explanation of Class Diagram

  • BaseStrategy class is an abstract class which represents the algorithm.
  • executeAlgorithm() is the abstract method in BaseStrategy which is responsible for executing the algorithm, but is puposefully kept abstract so that each of the child strategies/algorithms can implement this method with their own logic.
  • ConcreteStrategy1 & ConcreteStrategy2 are two subclasses of BaseStrategy. These 2 are infact two different variants of the algorithm represented by the BaseStrategy.
  • ConcreteStrategy1 & ConcreteStrategy2 override executeAlgorithm() method from BaseStrategy to provide the implementation of the algorithm variant as per their own needs.
  • Lastly, the Context class invokes this algorithm. Based on the need of the execution context specific variant of the BaseStrategy – either of ConcreteStrategy1 or ConcreteStrategy2 is assigned to the baseStrategyInstance variable of Context.
  • Context always invokes baseStrategyInstance variable’s executeAlgorithm() method, but the actual algorithm which is executed is based on which instance of ConcreteStrategy is held by baseStrategyInstance.

Note – I have shown 2 concrete instances named ConcreteStrategy1 & ConcreteStrategy2 just for explanation. There can be more than 2 concrete instances as per needs of the design.

Strategy Design Pattern – Example Use Case in Java

Strategy Design Pattern in Java Class Diagram
Code for the classes shown in Java Example’s Class Diagram
//BaseFileParser.java
public abstract class BaseFileParser{
  public abstract void parseFile();
}
//XMLFileParser.java
public class XMLFileParser extends BaseFileParser{
  public void parseFile(){
    //Logic for parsing an XML file goes here
  } 
}
//CSVFileParser.java
public class CSVFileParser extends BaseFileParser{
  public void parseFile(){
    //Logic for parsing a CSV file goes here
  } 
}
//Client.java
public class Client{
  private BaseFileParser baseFileParser;
  public Client(BaseFileParser baseFileParser){
    this.baseFileParser=baseFileParser;
  }  
  public void parseFile(){
    baseFileParser.parseFile();
  } 
  public static void main(String args[]){
    //Lets say the client needs to parse an XML file
    //The file type(XML/CSV) can also be taken as 
    //input from command line args[]
    Client client=new Client(new XMLFileParser());
    client.parseFile();
  }
}
Explanation of Code & Class Diagram
The Java Example’s Class Diagram is for a family of algorithms for file parsers where –

  • BaseFileParser class is an abstract base class which represents family of FileParser instances in the design. It has a single abstract method parseFile() which needs to be invoked to parse a file. This method will be overridden by individual parsers next.
  • XMLFileParser & CSVFileParser both implement BaseFileParser. Both also override parseFile() method as per their own logic for processing information in XML and CSV formats.
  • Client class needs to parse files and hence is a consumer of FileParser instances.
  • Client class holds an instance of BaseFileParser which is initialized with the correct subtype of XMLFileParser or CSVFileParser. This happens at the time of instantiation of the Client using a parameterized constructor which assigns the correct file parser to the baseFileParser variable.
  • When Client class’s parseFile() method is invoked, it in turn invokes parseFile() method of the child of BaseFileParser(XMLFileParser or CSVFileParser) which is contained in baseFileParser variable at that moment.
  • Thus, appropriate CSV or XML file parsing happens based on the context.
  • As you might have noticed in the main() method that the information of which child parser(CSV or XML) is to be assigned to the Client’s baseFileParser variable will be passed at runtime. This information can also be passed through the command line arguments args[]
  • So, Client is able to parse the incoming file by selecting at runtime one of the strategies of CSV or XML based.
  • If another file format, say PDF, needs to be implemented in future then all we need is to create a new subclass of BaseFileParser called PDFFileParser and implement PDF file handling logic in its parseFile() method.

Summary
This concludes the article on strategy design pattern where we looked at what is the pattern, pattern class diagram and its explanation and finally an example of the pattern in java with class diagram and sample code.

 

Digiprove sealCopyright © 2014-2016 JavaBrahman.com, all rights reserved.