Design Pattern Compilation

Command Pattern

The client passes a request, this request gets propagated as a command. The command request maps to particular modules. According to the command, a module is invoked.

This pattern is different from the Chain of Responsibility in a way that, in the earlier one, the request passes through each of the classes before finding an object that can take the responsibility. The command pattern however finds the particular object according to the command and invokes only that one.

Interface Order.java

Stock.java

BuyStock.java

SellStock.java

Broker.java

CommandPatternDemo.java

Output:

Stock [ Name: HDFC.Quantity: 100 ] bought
Stock [ Name: HDFC.Quantity: 100 ] sold

———————————————————————————————————————

Singleton Pattern

————————————————————————————————————————–

Prototype pattern

Suppose we have an Object that loads data from database. Now we need to modify this data in our program multiple times, so its not a good idea to create the Object using new keyword and load all the data again from database. So the better approach is to clone the existing object into a new object and then do the data manipulation.

 

Employees.java

Notice that the clone method is overridden to provide a deep copy of the employees list.

Here is the test program that will show the benefit of prototype pattern usage.

PrototypePatternTest.java

Output of the above program is:

emps List: [Shailesh, Raj, David, Lisa]

empsNew List: [Shailesh, Raj, David, Lisa, John]

empsNew1 List: [Raj, David, Lisa]

Consequences of Prototype Pattern:

  • Classes that have circular references to other classes cannot really be cloned.
  • One Difficulty in implementing the Prototype Pattern in Java is that if the classes already exist,we may not be able to change them to add the required clone or deepClone methods.The deepClone() method can be difficult if all the class objects contained in the class cannot be declared to implement Serializable.
  • Finally idea of having prototype classes to copy implies that we have sufficient access to the data or methods to these prototype classes so that we can modify the data once we have cloned the class.

Disadvantages :

Drawback to using the Prototype is that making a copy of an object can sometimes be complicated.

Producer Consumer Pattern

Benefit of Producer Consumer Pattern

1) Producer Consumer Pattern simple development. you can Code Producer and Consumer independently and Concurrently, they just need to know shared object.

2) Producer doesn’t need to know about who is consumer or how many consumers are there. Same is true with Consumer.

3) Producer and Consumer can work with different speed. There is no risk of Consumer consuming half-baked item.
In fact by monitoring consumer speed one can introduce more consumer for better utilization.

4) Separating producer and Consumer functionality result in more clean, readable and manageable code.

Solving Producer Consumer Problem in Multi-threading :

This problem can be implemented or solved by different ways in Java, One way is using wait and notify method to communicate between Producer and Consumer thread and blocking each of them on individual condition like full queue and empty queue.
With introduction of BlockingQueue Data Structure in Java 5 Its now much simpler because BlockingQueue provides this control implicitly by introducing blocking methods put() and take(). Now you don’t require to use wait and notify to communicate between Producer and Consumer.
BlockingQueue put() method will block if Queue is full in case of Bounded Queue and take() will block if Queue is empty.

Using Blocking Queue to implement Producer Consumer Pattern

BlockingQueue amazingly simplifies implementation of Producer-Consumer design pattern by providing outofbox support of blocking on put() and take(). Developer doesn’t need to write confusing and critical piece of wait-notify code to implement communication.

BlockingQueue is an interface and Java 5 provides different implimentation like ArrayBlockingQueue and LinkedBlockingQueue , both implement FIFO order or elements, while ArrayBlockingQueue is bounded in nature LinkedBlockingQueue is optionally bounded. here is a complete code example of Producer Consumer pattern with BlockingQueue. Compare it with classic wait notify code, its much simpler and easy to understand.

ProducerConsumerPattern.java

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ProducerConsumerPattern {

public static void main(String args[]){

//Creating shared object
BlockingQueue sharedQueue = new LinkedBlockingQueue();

//Creating Producer and Consumer Thread
Thread prodThread = new Thread(new Producer(sharedQueue));
Thread consThread = new Thread(new Consumer(sharedQueue));

//Starting producer and Consumer thread
prodThread.start();
consThread.start();
}

}

//Producer Class in java
class Producer implements Runnable {

private final BlockingQueue sharedQueue;

public Producer(BlockingQueue sharedQueue) {
this.sharedQueue = sharedQueue;
}

@Override
public void run() {
for(int i=0; i<10; i++){
try {
System.out.println(“Produced: ” + i);
sharedQueue.put(i);
} catch (InterruptedException ex) {
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

}

//Consumer Class in Java
class Consumer implements Runnable{

private final BlockingQueue sharedQueue;

public Consumer (BlockingQueue sharedQueue) {
this.sharedQueue = sharedQueue;
}

@Override
public void run() {
while(true){
try {
System.out.println(“Consumed: “+ sharedQueue.take());
} catch (InterruptedException ex) {
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

}

Output:

Produced: 0
Produced: 1
Consumed: 0
Produced: 2
Consumed: 1
Produced: 3
Consumed: 2
Produced: 4
Consumed: 3
Produced: 5
Consumed: 4
Produced: 6
Consumed: 5
Produced: 7
Consumed: 6
Produced: 8
Consumed: 7
Produced: 9
Consumed: 8
Consumed: 9

You see Producer Thread produced number and Consumer thread consumes it in FIFO order because blocking queue allows elements to be accessed in FIFO.


Proxy Pattern

There are four common situations in which the Proxy pattern is applicable.

  • It can be used in Virtual Proxy scenario—Consider a situation where there is multiple database call to extract huge size image. Since this is an expensive operation so here we can use the proxy pattern which would create multiple proxies and point to the huge size memory consuming object for further processing. The real object gets created only when a client first requests/accesses the object and after that we can just refer to the proxy to reuse the object. This avoids duplication of the object and hence saving memory.
  • It can be used in Protective Proxy scenario—It acts as an authorization layer to verify that whether the actual user has access the appropriate content or not. For example, a proxy server which provides restriction on internet access in office. Only the websites and contents which are valid will be allowed and the remaining ones will be blocked.
  • It can be used in Remote Proxy scenario—A remote proxy can be thought about the stub in the RPC call. The remote proxy provides a local representation of the object which is present in the different address location. Another example can be providing interface for remote resources such as web service or REST resources.
  • It can be used in Smart Proxy scenario—A smart proxy provides additional layer of security by interposing specific actions when the object is accessed. For example, to check whether the real object is locked or not before accessing it so that no other objects can change it.

Implementation:

Real internet class
Proxy internet class
proxy demo class

Output:
Connecting to technicalstack.com
Company restricted this site view


Factory Pattern

 

Factory design pattern is used when we have a super class with multiple sub-classes and based on input, we need to return one of the sub-class.

A factory is a Java class that is used to encapsulate object creation code. A factory class instantiates and returns a particular type of object based on data passed to the factory. The different types of objects that are returned from a factory typically are subclasses of a common parent class.

The data passed from the calling code to the factory can be passed either when the factory is created or when the method on the factory is called to create an object. This creational method is often called something such as getInstance or getClass .

Circle.java
Rectangle.java
Square.java
ShapeFactory.java
FactoryPatternDemo.java

Output

Inside draw method of Circle….
Inside draw method of Square….
Inside draw method of Rectangle….


   

Share :Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

Comments are closed