Object Functional Paradigm – Subsume the Strategy Pattern

My first blog is inspired by quote from  Venkat Subramanium in his book “Functional Programming in Java 8”.

“The common, familiar design patterns are more approachable when we design with lambda expressions; we need fewer lines of code, classes, and interfaces, and far less ceremony to implement our designs.”

Other inspirations are Dhaval Dalal who lately got us introduced to Functional Programming. And lastly Naresh Jain whose Object Boot Camp provoked a thought of building a good habit of writing Blogs for our own good.

We look at how we can subsume the Strategy Pattern. I would take examples complex just enough to convey the intent so that they remain concise and easy to digest.

In Object world, Operations like addition , multiplication , subtraction can be viewed as Strategies that act on two numbers , Integers in our case to give an Integer as a result.

In OOP context this can be implemented using Strategy pattern. Here just for convenience we start with a simple interfact OperationStrategy with one apply method.


package com.functProg.examples.subsumingStrategy;

public interface OperationStrategy {

public abstract int apply(int x,int y);

}

In normal OOP way we would have to write classes implementing the OperationStrategy Interface. Another better way as we just have a single method interface is to write anonymous inner classes with the strategies we want to implement. Then these strategies are passed to the calling class and basically the passing type decides the appropriate operation.

public class StrategyOOPWay {

 private OperationStrategy operationStrategy;

 public StrategyOOPWay(OperationStrategy os) {
 operationStrategy = os;
 }

 private int applyStrategyOn(int i, int j) {
 return operationStrategy.apply(i, j);
 }

 public static void main(String[] args) {

 OperationStrategy addStrategy = new OperationStrategy() {
 @Override
 public int apply(int x, int y) {
 return x + y;
 }
 };

 OperationStrategy multiplyStrategy = new OperationStrategy() {
 @Override
 public int apply(int x, int y) {
 return x * y;
 }
 };

 System.out.println(" Add "
 + new StrategyOOPWay(addStrategy).applyStrategyOn(10, 0));
 System.out.println(" Multiply "
 + new strategyOOPWay(multiplyStrategy).applyStrategyOn(10, 20));
 }

}

Output

Add 30
Multiply 200

STEP 1 : Refactoring using Lambdas

With the powerful expressive syntax of Lamda expressions the above code can be easily refactored in Java 8 where the anonymous classes we generated for strategies can be substituted by appropriate lambdas. Now with lambda expressions the same code can be converted to something given below. Note that java internally converts the lambda input to appropriate apply method of OperationStrategy. For our STEP 1 refactoring we maintain the OperationStrategy Interface as is.

package com.functProg.examples.subsumingStrategy;

public interface OperationStrategy {

 public abstract int apply(int x,int y);
}


package com.functProg.examples.subsumingStrategy;

public class StrategyLambdaWay {

 private OperationStrategy operationStrategy;

 public StrategyLambdaWay(OperationStrategy os) {
 operationStrategy = os;
 }

 private int applyStrategyOn(int i, int j) {
 return operationStrategy.apply(i, j);
 }

 public static void main(String[] args) {

 System.out.println(" Add "
 + new StrategyLambdaWay((x, y) -> (x + y)).applyStrategyOn(10,20));
 System.out.println(" Multiply "
 + new StrategyLambdaWay((x, y) -> (x * y)).applyStrategyOn(10,20));
 }

}

Output

Add 30
Multiply 200

STEP 2 : Refactoring using @FunctionalInterface in our case Bifunction

If we think of the OperationStrategy Interface we created its an interface with a single unimplemented method apply that takes in two inputs as Integers and returns and Integer as output. In Java 8 terms this is BiFunction taking in two Integer arguments and returning Integer.  Now as we can pass functions as arguments and we have predefined FunctionalInterface call Bifunction which implements two parameter functions for us there is no need of a seperate custom Interface OperationStrategy in our case.

The whole code can be condensed to a form like this :

package com.functProg.examples.subsumingStrategy;
import java.util.function.BiFunction;

public class Strategy {

 private BiFunction<Integer, Integer, Integer> operationStrategy;

 public Strategy(BiFunction<Integer, Integer, Integer> os) {
 operationStrategy = os;
 }

 public static void main(String[] args) {
 System.out.println(" Add ------ :"
 + new Strategy((x, y) -> (x + y)).applyStrategyOn(10, 20));
 System.out.println(" Multiply -- :"
 + new Strategy((x, y) -> (x * y)).applyStrategyOn(10, 20));
 }

 private int applyStrategyOn(int i, int j) {
 return operationStrategy.apply(i, j);
 }

}

Output

Add —— :30
Multiply — :200

From the concise code and readability its easy to appreciate the power of lambdas and functional interfaces in Java 8 which help subsume many traditional OOP patterns to create elegant and readable code.

Advertisements

One thought on “Object Functional Paradigm – Subsume the Strategy Pattern

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s