Friday, 26 May 2017

Mediator pattern

Mediator pattern defines an object that encapsulates how a set of objects interact.

Participants
Mediator - defines the interface for communication between Colleague objects.

ConcreteMediator - implements the Mediator interface.
Implements the communication and transfer the messages between the colleague objects.

ConcreteColleague - communicates with other Colleagues through its.

Before Mediator Design Pattern

 After Mediator Design Pattern


                                                            

Chat application

package designpattern.mediator;

public interface IChatMediator {
    public void sendMessage(IUser from, IUser to, String msg);

    void addUser(IUser user);
}

import java.util.ArrayList;
import java.util.List;
public class ChatMediator implements IChatMediator {
      private List<IUser> users;

      public ChatMediator() {
            this.users=new ArrayList<>();
      }

      @Override
      public void addUser(IUser user) {
            this.users.add(user);
      }

      @Override
      public void sendMessage(IUser from, IUser to, String msg) {
            to.receive(from,msg);
      }
}

public abstract class IUser {
      protected IChatMediator mediator;
      protected String name;

      public IUser(IChatMediator med, String name){
            this.mediator=med;
            this.name=name;
      }

      public abstract void send(IUser to, String msg);

      public abstract void receive(IUser from,String msg);
}

public class User extends IUser {
      public User(ChatMediator med, String name) {
            super(med, name);
      }

      @Override
      public void send(IUser to, String msg) {
            System.out.println(this.name+": Sending Message="+msg);
            mediator.sendMessage(this, to,msg);
      }
     
      @Override
      public void receive(IUser from, String msg) {
            System.out.println("Delivered from "+from.name+" to "+this.name);
      }
}

public class ChatClient {
      public static void main(String[] args) {
            ChatMediator mediator = new ChatMediator();
            IUser john = new User(mediator, "john");
            IUser micheal = new User(mediator, "micheal");
           
            mediator.addUser(john);
            mediator.addUser(micheal);
           
            john.send(micheal, "hello micheal!");
           
            micheal.send(john, "hello john!");
      }
}

Output:
john: Sending Message=hello micheal!
Delivered from john to micheal
micheal: Sending Message=hello john!
Delivered from micheal to john

Mediator Pattern usage in JDK

Java Message Service (JMS) uses Mediator pattern along with Observer pattern to allow applications to subscribe and publish data to other applications.

java.util.Timer class schedule (i.e scheduleAtFixedRate) methods.

Java Concurrency Executor execute() method.

java.lang.reflect.Method invoke() method.

Shutdown Hook - addShutdownHook

public void addShutdownHook(Thread hook)

Registers a new virtual-machine shutdown hook.

The JVM shuts down: The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or the virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.

Examples: user presses ctrl+c on the command prompt, System.exit(int) method is invoked, user logoff, user shutdown etc.

The shutdown hook can be used to perform cleanup resource or save the state when JVM shuts down normally or abruptly. Performing clean resource means closing log file, sending some alerts or something else. So if you want to execute some code before JVM shuts down, use shutdown hook.

How it works?
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled. Finally, the virtual machine will halt.

Note that daemon threads will continue to run during the shutdown sequence, as will non-daemon threads if shutdown was initiated by invoking the exit method.

Once the shutdown sequence has begun it can be stopped only by invoking the halt method, which forcibly terminates the virtual machine.

Once the shutdown sequence has begun it is impossible to register a new shutdown hook or de-register a previously-registered hook. Attempting either of these operations will cause an IllegalStateException to be thrown.

Shutdown hooks should also finish their work quickly. When a program invokes exit the expectation is that the virtual machine will promptly shut down and exit.

addShutdownHook(Runnable r)

The addShutdownHook() method of Runtime class is used to register the thread with the Virtual Machine.

Syntax:
public void addShutdownHook(Runnable r){ }

The object of Runtime class can be obtained by calling the static factory method getRuntime().

Runtime r = Runtime.getRuntime();

Factory method

The method that returns the instance of a class is known as factory method.

Shutdown Hook example

package com.threads.shutdown;

class ShutDownHook extends Thread { 
    public void run(){ 
        System.out.println("cleanup.. shut down hook task"); 
    } 
}

package com.threads.shutdown;
public class TestShutDownHook { 
       public static void main(String[] args)throws Exception { 

              Runtime runtime= Runtime.getRuntime();
              runtime.addShutdownHook(new ShutDownHook());

              System.out.println("Now main sleeping.press ctrl+c to exit"); 
              try {
                     Thread.sleep(3000);
              } catch (InterruptedException e) {
                     System.out.println("Interrupted Exception");
              }
      } 
}

Output:
Now main sleeping.press ctrl+c to exit
cleanup.. shut down hook task

Shutdown Hook by annonymous class

public class TestShutDownHookOnFly { 
       public static void main(String[] args)throws Exception { 

              Runtime runtime = Runtime.getRuntime(); 
              runtime.addShutdownHook(new Thread() { 
                     public void run() { 
                           System.out.println("cleanup.. shut down hook task"); 
                     }}); 

              System.out.println("Now main sleeping... press ctrl+c to exit"); 
              try {
                     Thread.sleep(3000);
              } catch (InterruptedException e) {
                     System.out.println("Interrupted Exception");
              } 
       }
}
Related Posts Plugin for WordPress, Blogger...