Sunday, June 27, 2021

Behavioral Design Pattern - Interpreter Pattern Java

Behavioral Interpreter Design Pattern 

we're going to look at the interpreter design pattern. The interpreter pattern is a behavior pattern that you used to represent the grammar of a language. A lot of tools use this pattern when parsing various aspects of grammar. 

Let's look at some of the concepts considered when choosing this pattern.

 the concept surrounding why you would choose the interpreter pattern or that it represents grammar. This could be music notation or mathematical equations, or even another language. Compilers will use the interpreter pattern too often. 

 This goes hand in hand with representing the grammar, but we can then use it to interpret a sentence. This enables us to map out a domain-specific language. If you've ever used SQL or an XML parser, this is the exact thing that is. 

This pattern was designed to do define a language that can be interpreted to do things you'll often see an interpreter used when defining an abstract syntax tree. To examples of this in the Java API. The Java Util pattern, the pattern classes used to represent a compiled regular expression, is an incredibly powerful way to search through strings. Another representation is the java class format is an abstract-based class that is used to represent locale-sensitive content such as dates, numbers, and strings. Let's look at some of the design considerations when choosing this pattern.

 


 the design of the interpreter is quite a bit different than most of the other patterns that we've looked at. There is an abstract-based class or an abstract expression that declares an interface for executing an operation. That operation is an interpreted method. Expressions are then broken into terminal expressions, which represent a leaf of a tree or an expression that does not contain other expressions. If it does contain other expressions then it's a nonterminal expression. Nonterminal expressions represent compound expressions and continue. So we called itself a recursive tree until it finally represents a terminal expression or multiple subexpressions. 

The pieces of the UML diagram are the context, abstract expression, terminal expression, non-terminal expression, and a client.

 Example: Pattern

the pattern class used in conjunction with regular expressions is a good example of the interpreter pattern being used in the Java API. We created sentences and establish grammar for that sentence. From there, we're going to interpret the sentence and display what we parsed using the pattern. Let's look at this in life code now.

Code :

package interpreterpattern;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class InterpreterJavaAPIDemo {

public static void main(String[] args) {
String input = "Lions , and tigers , and bears! oh , my";
Pattern p = Pattern.compile("(Lions , and tigers , and bears! oh , my)");
Matcher m = p.matcher(input);
while (m.find()) {
System.out.println("Found a " + m.group() + ".");
}
}
}

Output :
Lions Bears is true

Demo Structure for real-time project implementation:

package interpreterpattern;

public class InterpreterDemo {

static Expression buildInterpreterTree() {

Expression terminal1 = new TerminalExpression("Lions");
Expression terminal2 = new TerminalExpression("Tigers");
Expression terminal3 = new TerminalExpression("Bears");

Expression alternation1 = new AndExpression(terminal2, terminal3);
Expression alternation2 = new OrExpression(terminal1, alternation1);

return new AndExpression(terminal3, alternation2);
}

public static void main(String[] args) {
// String context = "Lions";
// String context = "Tigers";
// String context = "Tigers";
//String context = "Lions Tigers";
String context = "Lions Bears";
Expression define = buildInterpreterTree();
System.out.println(context + " is " + define.interpret(context));
}
}
package interpreterpattern;

public interface Expression {

boolean interpret(String context);
}
package interpreterpattern;

public class OrExpression implements Expression {
private Expression expr1 = null;
private Expression expr2 = null;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
package interpreterpattern;

import java.util.StringTokenizer;

public class TerminalExpression implements Expression {

private String data;

public TerminalExpression(String data) {
this.data = data;
}

@Override
public boolean interpret(String str) {
StringTokenizer st = new StringTokenizer(str);
while (st.hasMoreTokens()) {
String test = st.nextToken();
if (test.equals(data)) {
return true;
}
}
return false;
}
}
package interpreterpattern;

public class AndExpression implements Expression {

private Expression expr1 = null;
private Expression expr2 = null;

public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}

@Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}

Output :

Lions Bears is true

Pitfalls

Now that we've created our own interpreter, let's look at some of the pitfalls of it. If the grammar becomes very complex, it can be difficult to maintain, as you noticed in our rule example that we had you could see very quickly that if I started adding these different answers or combinations, it could become a little bit interesting to try and debug and walkthrough. So complexity can be an issue there. There is at least one class per rule, so every time we create one of our new expressions were creating another class. Complex rules will require multiple classes to define them. That's where the difficulty of maintenance can come into play. The use of other patterns might help with your specific implementation of a complex interpreter, and adding a new variant requires us to change every variant of that class. The interpreter is a little unique compared to some of the other patterns that we have looked at because it is fairly specific to the problem that we're trying to solve to better understand when we should use this or a different pattern. Let's contrast it with the visitor pattern.

Contrast to Other Patterns

To contrast the interpreter pattern. Let's compare it with the visitor. The interpreter and the visitor are very similar in structure, but a different focus on implementation. The interpreter has access to properties because it contains the object. Functions are defined as methods, and since we extend implement the base interface, each interpret function is contained within a method. One drawback is that adding new functionality changes every variant recall the demo that we coated together when we were building the expression tree and the complexity that we could get by calm compounding those expressions together, the visitor is actually very similar to the interpreter, with some slight variations. Instead of having access to the properties we need, we have to implement the observer observable functionality to gain access to those properties similar to the interpreter. Functionality is found in one place, but it is in the visitors and not in the expression objects that were building and just like the interpreter. Adding a new variant requires changing every visitor. The focus is more about whether you're adding more expressions or grammar rules or adding new visitors to interact with, and that is the main focus on choosing one over the other.

Thanks.

 

Sunday, June 20, 2021

Trapping Rain Water Problem

There is a very good question about Trapping Rain Water for arrays. Today I will give two solutions for this problem, Naive vs Efficient Solution. Let's understand the problem first.

Trapping Rain Water




So in the above example, you can only store a maximum of 6 units of water.

I/p= arr[] = {2,0,2}

o/p = 2 you can collect 2 Units of water in these bars. 

we are given an array of positive integers 

The elements are represented as Bars and the question is 

how much water you can store in this bar?

2nd Example :

arr[] = {3 , 0 , 1 , 2, 5 }

o/p = 6 

So now we are calculating that how much water we can

calculate suppose first is of height 3 units, 2nd bar

is of the height of 0 unit and so on ......

 if  you sum all the bars height collectively then 

 you will get the answer.

 Code ;

package dsalgo;

public class TrappingRainWaterProblem {
// for input = arr[] = {3,0,1,2,5}
public static void main(String[] args) {

int arr[] = {3, 0, 1, 2, 5}, n = 5;
System.out.println("Naive Solution:" + getWater(arr, n));
System.out.println("Efficient Solution : " +
getWaterEfficientSolution(arr, n)); // efficient Solution
}

/*****Naive Solution****/
public static int getWater(int arr[], int n) {
int res = 0;

for (int i = 1; i < n - 1; i++) {
int lMax = arr[i];

for (int j = 0; j < i; j++)
lMax = Math.max(lMax, arr[j]);

int rMax = arr[i];

for (int j = i + 1; j < n; j++)
rMax = Math.max(rMax, arr[j]);

res = res + (Math.min(lMax, rMax) - arr[i]);
}
System.out.println("Naive Time : " + System.nanoTime());
return res;
}

public static int getWaterEfficientSolution(int arr[], int n) {
int res = 0;

int lMax[] = new int[n];
int rMax[] = new int[n];

lMax[0] = arr[0];
for (int i = 1; i < n; i++)
lMax[i] = Math.max(arr[i], lMax[i - 1]);


rMax[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--)
rMax[i] = Math.max(arr[i], rMax[i + 1]);

for (int i = 1; i < n - 1; i++)
res = res + (Math.min(lMax[i], rMax[i]) - arr[i]);

System.out.println("Efficient Time::" + System.nanoTime());
return res;
}

}

 

Output : 

Naive Time : 2745092805500

Naive Solution:6

Efficient Time::2745093880800

Efficient Solution : 6

Just increase the input array then you will see the visible difference in Naive vs. Efficient Solution.

I tried to solve it in a simplest way.


Behavioral Design Pattern - Command Pattern

 Command Design Pattern

So command design pattern is a behavioral pattern that lets you encapsulate. Each request is an object. Of curse, there are more reasons to implement that we will look into those reasons.

Why you would choose the command pattern? 

because it encapsulates. Each request is an object. If you have dealt with or are going to work with a large system, you'll quickly find that the business logic and functions inside that system can be very complex to maintain a debug if they're all just added in one file.

Another key reason for choosing this pattern is that each call back as a request is now object-oriented instead of just another method added insight of that growing class. Maintainability is also increased because the sender is decoupled from the processor. This will enable the system to be more flexible and grow over time, oftentimes, but not the only reason. You will use a command to add undo functionality to your application. The entire request should be contained within the command and then could be rolled back. 

 For Example, Runnable Pattern is a great example of a command Design Pattern. the design of the command is a little different than some of the other patterns and is sometimes argued that it breaks the principles of, oh design because there is an object per command, A command is a verb, and objects usually aren't verbs, but rather the methods inside them. But people have seemed to relax their view on this. The main contract of the command is the command interface, all implementations of actions or commands inside the framework will implement this interface and in its simplest form, just contains an execute method. This method is where all of the action is performed. In the case of an undue feature, the interface will also contain a UN execute or undue method. But this isn't required to adhere to the principles of this pattern. Advanced implementations of this pattern make use of reflection to completely decoupled the client from the receiver or processor using a callback. 

Most examples you see, though, are simpler than this version, and we're going to look at various examples is to see how to best exercise this action and implement it in your day-to-day use.


Code : Example -1 

package command;

public class CommandPattern {

public static void main(String[] args) {
Task t1 = new Task(10, 12); // encapsulates request
Task t2 = new Task(11, 13);

Thread thread1 = new Thread(t1);
Thread thread2 = new Thread(t2);

thread1.start();//invoker
thread2.start();
}
}

class Task implements Runnable {
int num1;
int num2;

public Task(int num1, int num2) {
this.num1 = num1;
this.num2 = num2;
}

@Override
public void run() { // executor
System.out.println(num1 * num2); // receiver
}
}

Example -2 :

package command;

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

// client
public class CommandPatternExercise {

public static void main(String args[]) {
Light bedroomLight = new Light();
Light kitchenLight = new Light();
Switch lightSwitch = new Switch();

Command toggleCommand = new ToggleCommand(bedroomLight);
lightSwitch.storeAndExecute(toggleCommand);
// lightSwitch.storeAndExecute(toggleCommand);
// lightSwitch.storeAndExecute(toggleCommand);
// lightSwitch.storeAndExecute(toggleCommand);
List<Light> lights = new ArrayList<>();
lights.add(bedroomLight);
lights.add(kitchenLight);

Command alllightsCommand = new AllLightsCommand(lights);
lightSwitch.storeAndExecute(alllightsCommand);

}
}
package command;

// receiver
public class Light {

private boolean isOn = false;

public boolean isOn() {
return isOn;
}

public void toggle() {
if (isOn) {
off();
isOn = false;
} else {
on();
isOn = true;
}
}

private void on() {
System.out.println("Light switched on.");
}

private void off() {
System.out.println("Light switched off.");
}
}

  package command;


//invoker
public class Switch {

public void storeAndExecute(Command command) {
command.execute();
}
}
package command;

public class ToggleCommand implements Command {

private Light light;

public ToggleCommand(Light light) {
this.light = light;
}

@Override
public void execute() {
light.toggle();
}

} 

Output :


Light switched on.

Light switched off.

So we can implement this design pattern in our real-time project and can extract lots of benefits from it. I learn this pattern 10 years ago Since I am using it from time to time in my projects.

What are some of the pitfalls of a command? 

It's typically used with other patterns to be more mature. The dependence on other patterns isn't necessarily a bad thing. It just requires more knowledge on the developer's part. I also often see people struggle with the use of multiple commands. Frequently, I see people make the mistake of duplicating logic in another command. A better way to do this is either the use of a composite pattern as we demonstrated or commands. Combined with the chain of responsibility pattern for undo functionality, you may want to look at it using the memento pattern to handle state. If you're tracking objects that need to store history, you may need to also look at the prototype pattern for creating copies of commands to store on a list to get a better idea. When we shouldn't or shouldn't use this pattern.

to contrast the command pattern. Let's compare it with the strategy. The command is structured around an object per command or per request. The class contains essentially, what we're trying to do. It also encapsulates CE in the entire action. The command object on Lee deals with this one exact scenario. Thes strategy, on the other hand, is similar to the command in that it is an object per request, with the focus on this pattern being per strategy different than the command. Though the strategy focuses on the how rather than the what. Instead of encapsulating the action, it encapsulates the algorithm. The structure of these patterns is very similar, though with just some slight variations.

That's it.




Saturday, June 12, 2021

Chain Of Responsibility Design Pattern in JAVA

Why you would choose the chain of responsibility pattern?

Because they decouple the sender and receiver objects often times in an application. 
We want to pass a request to a receiving object without knowing who the sender was and vice versa. The sender shouldn't have to know who the receiver was in order for to process that request. When using the chain, the receiver should also contain a reference to the next receiver or the successor. This is an important part when choosing and implementing this pattern.

 It doesn't know the whole hierarchy, but it does know who's next in line. One of the main reasons for choosing this pattern is to promote loose coupling. 

We can modify the chain and add links to the chain without rewriting large portions of logic in the application. It should also be okay that there may not be a handler for a given request, and the application will just continue on examples of this in the job. For example how spring implements their security chain filter in spring security.

I will give two example one JAVA API reference and We will create one for us with real time example.

First lets have a look into the UML Diagram for the same.

UML Diagram:





Lets understand why we should consider this design pattern as you have seen the UML diagram.

the design of the chain Responsibility has a chain of receiver objects. This can be implemented in a number of ways, but some basic form of a list is typically the most common. Each handler is based off of a main interface that defines the contract between each chain link. There is a concrete handler for each receiver or implementation that will interpret a request in building the chain. Each handler has a reference to its successor or the next link in the chain. The pieces of the UML diagram are a handler and a concrete handler and then its successor.

Lets look into the code:

import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ChainOfresponsibility
{
private static final Logger logger = Logger.getLogger(ChainOfresponsibility.class.getName());
public static void main(String[] args)
{
logger.setLevel(Level.FINER);
ConsoleHandler handler = new ConsoleHandler();
handler.setLevel(Level.FINER);
logger.addHandler(handler);
logger.finest("Finest");
logger.finer("Finer");
logger.fine("Fine");
}
}


Output:

Jun 12, 2021 3:30:09 PM ChainOfresponsibility main
FINER: Finer
Jun 12, 2021 3:30:09 PM ChainOfresponsibility main

For Full source code go to my GitHub URL mentioned below:

https://github.com/Abhinaw/DesignPatternInJava/tree/master/src/chainofresponsibility
Here you will get all the required files for complete source code.



Let me explain the example that i took to implement this design pattern.
we have a hierarchy in our company such as CEO -> VP -> Director right?
So Director have some specific limited rights and VP have more rights as compared to Director and obviously, CEO have all the rights he can do anything he wants. here we have chain of responsibility.
More certainly, lets take example that Director can approve a purchase of Rs,1000 only and if it is more than Rs,1000 then it got to VP for approval and if it more than that it should go to CEO for the approval.

public class ChainOfResponsibility {

    public static void main(String[] args) {
        Director director = new Director();
        VP vp = new VP();
        CEO ceo = new CEO();

        director.setSuccessor(vp);
        vp.setSuccessor(ceo);
        Request request = new Request(RequestType.CONFERENCE, 500);
        director.handleRequest(request);

        request = new Request(RequestType.PURCHASE, 1000);
        director.handleRequest(request);

        request = new Request(RequestType.PURCHASE, 2000);
        director.handleRequest(request);
    }


FINE: Fine