Home » Patterns » Design Patterns » Strategy Design Pattern and Single Responsibility and Open-Closed Principles

4 Flares Twitter 1 Facebook 0 Google+ 3 LinkedIn 0 Email -- Filament.io 4 Flares ×

Strategy design pattern is widely implemented to achieve interchangeable algorithmic behavior at runtime. As we know strategy pattern uses aggregation or composition instead of inheritance. It is a behavioral design pattern. The behaviors are defined in separate interfaces and the encapsulating classes that implement this interface.
Generally most of the SOLID principles can be identified from classes, and modules which are well defined and follow some of the design patterns. In this article we will see how strategy design pattern can be applied to a design and how the SOLID principles such as Single Responsibility and Open-closed principles can be ensured.
Related Articles:

Strategy Pattern and Open-Closed Principle

When design follows strategy pattern, the algorithmic behavior is separated out and implemented in separate interfaces and encapsulating subclasses. This decouples the behavior and the class that uses this behavior. The behavior can be changed without breaking the classes that use it. Also, the classes can switch between behaviors by changing the specific implementation used with very less or no code change. This ensures that classes are closed for modification and open for extension. In other words proper Strategy pattern implementation satisfies the open-closed principle.

Single Responsibility Principle (SRP) and Strategy Design Pattern

The Single Responsibility Principle (term coined by Robert C. Martin) is defined as “Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class.
The single responsibility makes a class more robust. A class which does more than a single task may be a good candidate to split and ensure that it performs a single task or responsibility.
The question is, how do we determine whether particular class features a set of responsibilities, or whether it has only one responsibility and is thus adhering to SRP? If your class has more than one non-cohesive responsibility, you definitely need to consider splitting it and create separate classes for each responsibility. You can have highly cohesive classes that feature a set of responsibilities that are strongly related. But a class to adhere to SRP should have just one responsibility. If a class has internal structure which is complex, that could be an indication of multiple responsibilities. You probably should refactor it so that, the responsibilities are packaged into separate smaller classes.
We will check all the above principles and its applicability while using Strategy Design pattern by creating an example Java program

Strategy Design Pattern Java Example

As we know design pattern and principles helps us to think and apply the appropriate design where it is required. In case of strategy pattern we need to think about the algorithms that can be separated out and can be used interchangeably at runtime.
For example, we can have different algorithms to retrieve search results from many different sources. This search strategy and its implementation logic are separated from the main context class. At runtime, the client code can decide on which search strategy he needs. Our example implementation below explains this.
Let us consider an application, which searches some asset availability from online services and local database.

The Strategy Interface

The classes that implement a concrete strategy should implement this interface. The SearchManager class uses this to call the concrete strategy.

/**
 * SearchStrategy.java
 * Jun 11, 2013
 * www.globinch.com
 * copyright http://www.globinch.com. All rights reserved.
 */
package com.globinch.pattern.strategy;

import java.util.List;

/**
 * SearchStrategy : The algorithm sperated from context.
 * @author Binu George
 * @since 2013
 * @version 1.0
 */
public interface SearchStrategy {
	/*
	 * Get the search results
	 */
	public List<SearchResult> search();
}

Concrete Strategy Classes

These concrete strategy classes implements the algorithm using the strategy interface (SearchStrategy).

/**
 * SearchOnline.java
 * Jun 11, 2013
 * www.globinch.com
 * copyright http://www.globinch.com. All rights reserved.
 */
package com.globinch.pattern.strategy;

import java.util.ArrayList;
import java.util.List;

/**
 * SearchOnline : Do an online search.
 * @author Binu George
 * @since 2013
 * @version 1.0
 */
public class SearchOnline implements SearchStrategy {

	/**
	 * Constructor
	 */
	public SearchOnline() {
		// TODO Auto-generated constructor stub
	}

	/* (non-Javadoc)
	 * @see com.globinch.pattern.strategy.SearchStrategy#search()
	 */
	@Override
	public List<SearchResult> search() {
		System.out.println("Doing an online search.");
		return new ArrayList<SearchResult>();
	}

}
/**
 * SearchDatabase.java
 * Jun 11, 2013
 * www.globinch.com
 * copyright http://www.globinch.com. All rights reserved.
 */
package com.globinch.pattern.strategy;

import java.util.ArrayList;
import java.util.List;

/**
 * TODO
 * @author Binu George
 * @since 2013
 * @version 1.0
 */
public class SearchDatabase implements SearchStrategy {

	/**
	 * Constructor
	 */
	public SearchDatabase() {
		// TODO Auto-generated constructor stub
	}

	/* (non-Javadoc)
	 * @see com.globinch.pattern.strategy.SearchStrategy#search()
	 */
	@Override
	public List<SearchResult> search() {
		System.out.println("Doing a local DB search.");
		return new ArrayList<SearchResult>();
	}

}

SearchManager class

The SearchManager is configured with a concrete strategy object and maintains a reference to a Strategy object.

/**
 * SearchManager.java
 * Jun 11, 2013
 * www.globinch.com
 * copyright http://www.globinch.com. All rights reserved.
 */
package com.globinch.pattern.strategy;

import java.util.List;

/**
 * The Search manager class.
 * @author Binu George
 * @since 2013
 * @version 1.0
 */
public class SearchManager {

	private SearchStrategy searchStrategy;
	/**
	 * Constructor
	 */
	public SearchManager() {
		// TODO Auto-generated constructor stub
	}
	/**
	 * @return the searchMode
	 */
	public SearchStrategy getSearchStrategy() {
		return searchStrategy;
	}
	/**
	 * @param searchMode the searchMode to set
	 */
	public void setSearchStrategy(SearchStrategy searchStrategy) {
		this.searchStrategy = searchStrategy;
	}
	/**
	 * Do a search
	 * @return List<SearchResult>
	 */
	public List<SearchResult> search(){
		return searchStrategy.search();
	}
}

Test class to test strategy implementation

/**
 * SearchTest.java
 * Jun 11, 2013
 * www.globinch.com
 * copyright http://www.globinch.com. All rights reserved.
 */
package com.globinch.pattern.strategy;

/**
 * TODO
 * @author Binu George
 * @since 2013
 * @version 1.0
 */
public class SearchTest {

	/**
	 * Constructor
	 */
	public SearchTest() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SearchManager manager = new SearchManager();
		manager.setSearchStrategy(new SearchOnline());
		manager.search();
		manager.setSearchStrategy(new SearchDatabase());
		manager.search();

	}

}
Doing an online search.
Doing a local DB search.

In the above example, you can add a new search algorithm by creating a new subclass of SearchStrategy. You don’t have to change any existing strategy implementations. The SearchManager needs changes only when it needs to include a new search strategy.

Strategy Pattern and Factory Pattern

Strategy patterns are used primarily as a way to decouple the logic/algorithm being used. The strategy pattern lets you decouple the algorithms used, to get some task execution and the decision making logic. The Strategy Pattern can be combined with creational patterns such as Factory Patterns. It allows you to decouple the concrete strategy from the client, by using Factories inside the context class( SearchManager in our example). Read the below article to know more about different factory patterns.
Factory Design Patterns and Open-Closed Principle (OCP), the ‘O’ in SOLID
The Single Responsibility Principle (SRP) guides you in identifying classes, and separating the responsibilities during the design phase of an application.

Incoming search terms:

4 Flares Twitter 1 Facebook 0 Google+ 3 LinkedIn 0 Email -- Filament.io 4 Flares ×

About Binu George

One thought on “Strategy Design Pattern and Single Responsibility and Open-Closed Principles

  1. Zhuo Li says:

    Very helpful!
    Thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *

Paged comment generated by AJAX Comment Page

Google+ Plus Follow on Twitter Like On Facebook Linked Follow

Popular post

JAX-WS Web Services and Clients Java JAX-WS Tutorial: Develop Web Services and Clients (Consumers) Using JAX-WS
jax-ws usernametoken example JAX-WS and Secure Java Web Services using UsernameToken : WS-Security with Metro and WSIT
How to Fix : java.security.cert.CertificateException: No name matching localhost found
JAX-WS exception fault handling example JAX-WS Exceptions and Faults: Annotation, Exception and Fault Handling Examples
SOAP Binding: Difference between Document and RPC Style Web Services

Subscribe to Enterprise Java newsletter
Subscribe
Get Enterprise Java Newsletter

Enter your email and stay on top of things,