Facade Design Pattern

A Design Pattern is a documented and prooven design solution, which can be used to solve commonly occurring Design Problems.

A Facade Design Pattern is providing Simple, Single Unified interface to a set of classes. Below is an example of the same.

As shown in below diagram, an Application is directly dependent on Display, FileSystem, Networking etc….we are assuming each of these services are provided by corresponding class. Without using Facade Pattern, Application is directly dependent on the classes.

But by re designing above solution by using facade Pattern, Application is not directly dependent on each of individual classes, Hence any change in the public methods exposed by the individual class or change of class, may not directly impact Application. If any changes in the individual classes, changes need to be performed in the UnifiedAPI, and hence Application need not be changed.

Facade Pattern
Facade Pattern



class FileSystem{

   public void readFile() {
      System.out.println("readFile() in FileSystem");
   }
}

class Network {

   public void sendData() {
      System.out.println("sendData() in Network");
   }
}


class Display {

   public void draw() {
      System.out.println("draw() in Display");
   }
}

class AppLifeCycle {

   public void startApp() {
      System.out.println("startApp() in AppLifeCycle");
   }
}

interface OSAPI{
    public void readFileOS();
    public void sendDataOS();
    public void startAppOS();
    public void drawOS(); 
}

class FacadeClass implements OSAPI{
      public void readFileOS(){
          new FileSystem().readFile();
      }
      
    public void sendDataOS(){
            new Network().sendData();
    }
    
    public void startAppOS(){
        new AppLifeCycle().startApp();
    }
    
    public void drawOS(){
        new Display().draw();
    }
}

public class FacadePattern1 {
   public static void main(String[] args) {
      FacadeClass obj = new FacadeClass();

      obj.drawOS();
      obj.readFileOS();
      obj.sendDataOS();
      obj.startAppOS();
   }
}

purpose of wait() and notify() methods in Object class

As briefed in all methods of Object class these methods are final and defined in java.lang.Object class. Hence these methods are available in each and every class, because Object class is base class of all classes, in Java. These methods can be invoked only from synchronized block or synchronized method.
wait(); – It tells the calling thread to give up the lock and go to sleep until some other thread calls notify() method on same object.
notify(); -It wakes up one single thread that called wait() on the same object.
notifyAll(); – It wakes up all the threads that called wait() on the same object.
These methods can be used to solve producer consumer related problems.

Below is simple example in which Main thread invokes wait() on threadb, after threadb computes total sum, it invokes notify() method, so that Main thread gets the control, and prints total value.

public class NotifyWait {
	public static void main(String[] args) {
		NotifyWaitB b = new NotifyWaitB();
		b.start();
			synchronized(b){
			try{
				System.out.println("A:waiting for b thread to complete...");
				b.wait();
			}catch(Exception e) {
				System.out.println("Interrupted Exception:"+e.getMessage());
				//e.printStackTrace();
			}		
			System.out.println("Total is:"+b.total);
		}
	}
}


class NotifyWaitB extends Thread{
	int total;	
	public void run(){		
		System.out.println("in run() method of Child thread");
		synchronized(this)
		{
			for(int i=0;i<30;i++)
			{
				total += i;				
			}			
			notify();
			System.out.println("notify() invoked from Child thread");
		}		
	}
}

Below is some real time example on using wait() and notify() methods.

wait-notify-notifyall-example
wait-notify-notifyall-example

Here Display Thread, need to continuously check(with a infinite loop or so) Packet Queue, to find if new Packets are available, which may not be a professional approach. As continuously checking Packet Queue, may waste CPU time, and may adversely affect performance of overall Application. This problem can be solved better, by using wait() and notify(). Below are the steps involved…

Downloader Thread downloads packets, adds to Queue.
Calls notify() method on Queue, which wakes up Display Thread.

Now display Thread reads packets from Queue, processes them.
Calls wait() method on Queue, which goes on sleep, until notify() is called by Downloader Thread.

You may also like to read:
how to use join() method between child threads?
how to avoid deadlock in threads
can a child thread start another child thread?

Can Thread join() be used between two child Threads

Refer purpose of join method in multi threading , for basic details on join() method. Generally a parent Thread invokes join() method on one or more child threads, that means parent thread gets suspended, until its one or more of its child threads completes execution. As shown in below example it is possible to use join() method between child threads as well.


class ThreadA extends Thread
{
	public void run(){
		for(int i=0;i<10;i++)
		{
			try{
			System.out.println("ThreadA:"+i);
			Thread.sleep(1000);
			}catch(Exception et)
			{
				System.out.println(et);
			}
		}
	}
}

class ThreadB extends Thread
{
	public void run(){
		System.out.println("run() in ThreadB");
		try{
		JoinBetweenChildThreads.ta.join();
		
		for(int i=20;i<30;i++)
		{
			System.out.println("ThreadB:"+i);
			Thread.sleep(1000);
		}	
		}catch(Exception et){ System.out.println(et); }
	}
}

public class JoinBetweenChildThreads {
	static ThreadA ta;
	static ThreadB tb;
	
	public static void main(String[] args) {
		ta = new ThreadA();
		tb = new ThreadB();
		
		ta.start();
		tb.start();
	}
}