Java/Design Pattern/Call Back Pattern

Материал из Java эксперт
Перейти к: навигация, поиск

Callback Pattern in Java

   <source lang="java">

//[C] 2002 Sun Microsystems, Inc.--- import java.io.IOException; public class RunCallbackPattern {

   public static void main(String [] arguments){
       System.out.println("Example for the Callback pattern");
       System.out.println("This code will run two RMI objects to demonstrate");
       System.out.println(" callback capability. One will be CallbackClientImpl,");
       System.out.println(" which will request a project from the other remote");
       System.out.println(" object, CallbackServerImpl.");
       System.out.println("To demonstrate how the Callback pattern allows the");
       System.out.println(" client to perform independent processing, the main");
       System.out.println(" progam thread will go into a wait loop until the");
       System.out.println(" server sends the object to its client.");
       System.out.println();
       
       System.out.println("Running the RMI compiler (rmic)");
       System.out.println();
       try{
           Process p1 = Runtime.getRuntime().exec("rmic CallbackServerImpl");
           Process p2 = Runtime.getRuntime().exec("rmic CallbackClientImpl");
           p1.waitFor();
           p2.waitFor();
       }
       catch (IOException exc){
           System.err.println("Unable to run rmic utility. Exiting application.");
           System.exit(1);
       }
       catch (InterruptedException exc){
           System.err.println("Threading problems encountered while using the rmic utility.");
       }
       
       System.out.println("Starting the rmiregistry");
       System.out.println();
       Process rmiProcess = null;
       try{
           rmiProcess = Runtime.getRuntime().exec("rmiregistry");
           Thread.sleep(15000);
       }
       catch (IOException exc){
           System.err.println("Unable to start the rmiregistry. Exiting application.");
           System.exit(1);
       }
       catch (InterruptedException exc){
           System.err.println("Threading problems encountered when starting the rmiregistry.");
       }
       
       System.out.println("Creating the client and server objects");
       System.out.println();
       CallbackServerImpl callbackServer = new CallbackServerImpl();
       CallbackClientImpl callbackClient = new CallbackClientImpl();
       
       System.out.println("CallbackClientImpl requesting a project");
       callbackClient.requestProject("New Java Project");
       
       try{
           while(!callbackClient.isProjectAvailable()){
               System.out.println("Project not available yet; sleeping for 2 seconds");
               Thread.sleep(2000);
           }
       }
       catch (InterruptedException exc){}
       System.out.println("Project retrieved: " + callbackClient.getProject());
   }

} import java.rmi.Naming; import java.rmi.server.UnicastRemoteObject; public class CallbackServerImpl implements CallbackServer{

   private static final String CALLBACK_SERVER_SERVICE_NAME = "callbackServer";
   public CallbackServerImpl(){
       try {
           UnicastRemoteObject.exportObject(this);
           Naming.rebind(CALLBACK_SERVER_SERVICE_NAME, this);
       }
       catch (Exception exc){
           System.err.println("Error using RMI to register the CallbackServerImpl " + exc);
       }
   }
   
   public void getProject(String projectID, String callbackMachine,
     String callbackObjectName){
       new CallbackServerDelegate(projectID, callbackMachine, callbackObjectName);
   }
   

} import java.rmi.Remote; import java.rmi.RemoteException; public interface CallbackServer extends Remote{

   public void getProject(String projectID, String callbackMachine,
     String callbackObjectName) throws RemoteException;

}

import java.net.InetAddress; import java.net.MalformedURLException; import java.net.UnknownHostException; import java.rmi.Naming; import java.rmi.server.UnicastRemoteObject; import java.rmi.NotBoundException; import java.rmi.RemoteException; public class CallbackClientImpl implements CallbackClient{

   private static final String CALLBACK_CLIENT_SERVICE_NAME = "callbackClient";
   private static final String CALLBACK_SERVER_SERVICE_NAME = "callbackServer";
   private static final String CALLBACK_SERVER_MACHINE_NAME = "localhost";
   
   private Project requestedProject;
   private boolean projectAvailable;
   
   public CallbackClientImpl(){
       try {
           UnicastRemoteObject.exportObject(this);
           Naming.rebind(CALLBACK_CLIENT_SERVICE_NAME, this);
       }
       catch (Exception exc){
           System.err.println("Error using RMI to register the CallbackClientImpl " + exc);
       }
   }
   
   public void receiveProject(Project project){
       requestedProject = project;
       projectAvailable = true;
   }
   
   public void requestProject(String projectName){
       try{
           String url = "//" + CALLBACK_SERVER_MACHINE_NAME + "/" + CALLBACK_SERVER_SERVICE_NAME;
           Object remoteServer = Naming.lookup(url);
           if (remoteServer instanceof CallbackServer){
               ((CallbackServer)remoteServer).getProject(projectName,
                  InetAddress.getLocalHost().getHostName(),
                  CALLBACK_CLIENT_SERVICE_NAME);
           }
           projectAvailable = false;
       }
       catch (RemoteException exc){}
       catch (NotBoundException exc){}
       catch (MalformedURLException exc){}
       catch (UnknownHostException exc){}
   }
   
   public Project getProject(){ return requestedProject; }
   public boolean isProjectAvailable(){ return projectAvailable; }

}

import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; public class CallbackServerDelegate implements Runnable{

   private Thread processingThread;
   private String projectID;
   private String callbackMachine;
   private String callbackObjectName;
   
   public CallbackServerDelegate(String newProjectID, String newCallbackMachine,
     String newCallbackObjectName){
       projectID = newProjectID;
       callbackMachine = newCallbackMachine;
       callbackObjectName = newCallbackObjectName;
       processingThread = new Thread(this);
       processingThread.start();
   }
   
   public void run(){
       Project result = getProject();
       sendProjectToClient(result);
   }
   
   private Project getProject(){
       return new Project(projectID, "Test project");
   }
   
   private void sendProjectToClient(Project project){
       try{
           String url = "//" + callbackMachine + "/" + callbackObjectName;
           Object remoteClient = Naming.lookup(url);
           if (remoteClient instanceof CallbackClient){
               ((CallbackClient)remoteClient).receiveProject(project);
           }
       }
       catch (RemoteException exc){}
       catch (NotBoundException exc){}
       catch (MalformedURLException exc){}
   }

}

import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; public class CallbackServerWorkThread implements Runnable{

   private Thread processingThread;
   private String projectID;
   private String callbackMachine;
   private String callbackObjectName;
   
   public CallbackServerWorkThread(String newProjectID, String newCallbackMachine,
     String newCallbackObjectName){
       projectID = newProjectID;
       callbackMachine = newCallbackMachine;
       callbackObjectName = newCallbackObjectName;
       processingThread = new Thread(this);
       processingThread.start();
   }
   
   public void run(){
       Project result = getProject();
       sendProjectToClient(result);
   }
   
   private Project getProject(){
       return new Project(projectID, "Test project");
   }
   
   private void sendProjectToClient(Project project){
       try{
           String url = "//" + callbackMachine + "/" + callbackObjectName;
           Object remoteClient = Naming.lookup(url);
           if (remoteClient instanceof CallbackClient){
               ((CallbackClient)remoteClient).receiveProject(project);
           }
       }
       catch (RemoteException exc){}
       catch (NotBoundException exc){}
       catch (MalformedURLException exc){}
   }

} public class Command implements java.io.Serializable{

   public static final int GET_PROJECT = 1;
   public static final int GET_TASK = 2;
   public static final int CREATE_CONTACT = 4;
   public static final int ADD_ADDRESS = 8;
   public static final int REMOVE_ADDRESS = 16;
   public static final int FINALIZE_CONTACT = 32;
   
   private int command;
   private Object [] arguments;
   
   public int getCommand(){
       return command;
   }
   
   public Object [] getArguments(){
       return arguments;
   }
   
   public void setArguments(Object [] newArguments){
       arguments = newArguments;
   }
   
   public void setCommand(int newCommand){
       command = newCommand;
   }
   
   public Command(int name, Object [] argumentList){
       command = name;
       arguments = argumentList;
   }

} import java.util.ArrayList; public class Project implements ProjectItem{

   private String name;
   private String description;
   private ArrayList projectItems = new ArrayList();
   
   public Project(){ }
   public Project(String newName, String newDescription){
       name = newName;
       description = newDescription;
   }
   
   public String getName(){ return name; }
   public String getDescription(){ return description; }
   public ArrayList getProjectItems(){ return projectItems; }
   
   public void setName(String newName){ name = newName; }
   public void setDescription(String newDescription){ description = newDescription; }
   
   public void addProjectItem(ProjectItem element){
       if (!projectItems.contains(element)){
           projectItems.add(element);
       }
   }
   
   public void removeProjectItem(ProjectItem element){
       projectItems.remove(element);
   }
   
   public String toString(){ return name + ", " + description; }

} import java.net.Socket; import java.util.Date; import java.io.*; public class ServerWorkThread implements Runnable{

   private Thread processingThread;
   private Socket requestSocket;
   private Command command;
   
   public ServerWorkThread(Socket clientRequestSocket){
       requestSocket = clientRequestSocket;
       processingThread = new Thread(this);
       processingThread.start();
   }
   
   private void retrieveCommand(){
       try{
           ObjectInputStream in = new ObjectInputStream(requestSocket.getInputStream());
           Object request = in.readObject();
           requestSocket.close();
           if (request instanceof Command){
               command = (Command)request;
           }
       }
       catch (ClassNotFoundException exc){
       }
       catch (IOException exc){
       }
   }
   
   protected void processCommand(){
   }
   
   public void run(){
       retrieveCommand();
       processCommand();
   }
   
   public Command getCommand(){
       return command;
   }
   
   protected Socket getRequestSocket(){
       return requestSocket;
   } 

}

import java.util.ArrayList; public class Task implements ProjectItem{

   private String name;
   private ArrayList projectItems = new ArrayList();
   private double timeRequired;
   
   public Task(){ }
   public Task(String newName, double newTimeRequired){
       name = newName;
       timeRequired = newTimeRequired;
   }
   
   public String getName(){ return name; }
   public ArrayList getProjectItems(){ return projectItems; }
   public double getTimeRequired(){ return timeRequired; }
   
   public void setName(String newName){ name = newName; }
   public void setTimeRequired(double newTimeRequired){ timeRequired = newTimeRequired; }
   
   public void addProjectItem(ProjectItem element){
       if (!projectItems.contains(element)){
           projectItems.add(element);
       }
   }
   
   public void removeProjectItem(ProjectItem element){
       projectItems.remove(element);
   }
   

}

import java.net.ServerSocket; import java.net.Socket; import java.io.IOException; public class ThreadedServer{

   private static final int DEFAULT_SERVER_PORT = 2001;
   
   private boolean shutdown;
   private int serverPort = DEFAULT_SERVER_PORT;
   
   public void runServer(){
       try{
           ServerSocket mainServer = new ServerSocket(serverPort);
           while (!shutdown){
               Socket requestSocket = mainServer.accept();
               new ServerWorkThread(requestSocket);
           }
       }
       catch (IOException exc){
       }
   }
   
   public int getServerPort(){
       return serverPort;
   }
   
   public boolean isShutdown(){
       return shutdown;
   }
   
   public void setShutdown(boolean isShutdown){
       shutdown = isShutdown;
   }
   
   public void setServerPort(int newServerPort){
       serverPort = newServerPort;
   }

}

import java.rmi.Remote; import java.rmi.RemoteException; public interface CallbackClient extends Remote{

   public void receiveProject(Project project) throws RemoteException;

} import java.io.Serializable; import java.util.ArrayList; public interface ProjectItem extends Serializable{

   public ArrayList getProjectItems();

}

      </source>
   
  
 
  



Chain Pattern

   <source lang="java">

//[C] 2002 Sun Microsystems, Inc.--- import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList;

import java.io.File; import java.util.ArrayList; import java.util.Iterator; public class RunChainPattern {

   public static void main(String [] arguments){
       System.out.println("Example for the Chain of Responsibility pattern");
       System.out.println();
       System.out.println("This code uses chain of responsibility to obtain");
       System.out.println(" the owner for a particular ProjectItem, and to");
       System.out.println(" build up a list of project details. In each case,");
       System.out.println(" a call to the appropriate getter method, getOwner");
       System.out.println(" or getDetails, will pass the method call up the");
       System.out.println(" project tree.");
       System.out.println("For getOwner, the call will return the first non-null");
       System.out.println(" owner field encountered. For getDetails, the method");
       System.out.println(" will build a series of details, stopping when it");
       System.out.println(" reaches a ProjectItem that is designated as a");
       System.out.println(" primary task.");
       System.out.println();
       
       System.out.println("Deserializing a test Project for Visitor pattern");
       System.out.println();
       if (!(new File("data.ser").exists())){
           DataCreator.serialize("data.ser");
       }
       Project project = (Project)(DataRetriever.deserializeData("data.ser"));
       
       System.out.println("Retrieving Owner and details for each item in the Project");
       System.out.println();
       getItemInfo(project);
   }
   
   private static void getItemInfo(ProjectItem item){
       System.out.println("ProjectItem: " + item);
       System.out.println("  Owner: " + item.getOwner());
       System.out.println("  Details: " + item.getDetails());
       System.out.println();
       if (item.getProjectItems() != null){
           Iterator subElements = item.getProjectItems().iterator();
           while (subElements.hasNext()){
               getItemInfo((ProjectItem)subElements.next());
           }
       }
   }

} interface Contact extends Serializable{

   public static final String SPACE = " ";
   public String getFirstName();
   public String getLastName();
   public String getTitle();
   public String getOrganization();
   
   public void setFirstName(String newFirstName);
   public void setLastName(String newLastName);
   public void setTitle(String newTitle);
   public void setOrganization(String newOrganization);

} class ContactImpl implements Contact{

   private String firstName;
   private String lastName;
   private String title;
   private String organization;
   
   public ContactImpl(){}
   public ContactImpl(String newFirstName, String newLastName,
       String newTitle, String newOrganization){
           firstName = newFirstName;
           lastName = newLastName;
           title = newTitle;
           organization = newOrganization;
   }
   
   public String getFirstName(){ return firstName; }
   public String getLastName(){ return lastName; }
   public String getTitle(){ return title; }
   public String getOrganization(){ return organization; }
   
   public void setFirstName(String newFirstName){ firstName = newFirstName; }
   public void setLastName(String newLastName){ lastName = newLastName; }
   public void setTitle(String newTitle){ title = newTitle; }
   public void setOrganization(String newOrganization){ organization = newOrganization; }
   
   public String toString(){
       return firstName + SPACE + lastName;
   }

} class Task implements ProjectItem{

   private String name;
   private ArrayList projectItems = new ArrayList();
   private Contact owner;
   private String details;
   private ProjectItem parent;
   private boolean primaryTask;
   
   public Task(ProjectItem newParent){
       this(newParent, "", "", null, false);
   }
   public Task(ProjectItem newParent, String newName,
       String newDetails, Contact newOwner, boolean newPrimaryTask){
           parent = newParent;
           name = newName;
           owner = newOwner;
           details = newDetails;
           primaryTask = newPrimaryTask;
   }
   
   public Contact getOwner(){
       if (owner == null){
           return parent.getOwner();
       }
       else{
           return owner;
       }
   }
   
   public String getDetails(){
       if (primaryTask){
           return details;
       }
       else{
           return parent.getDetails() + EOL_STRING + "\t" + details;
       }
   }
   
   public String getName(){ return name; }
   public ArrayList getProjectItems(){ return projectItems; }
   public ProjectItem getParent(){ return parent; }
   public boolean isPrimaryTask(){ return primaryTask; }
   
   public void setName(String newName){ name = newName; }
   public void setOwner(Contact newOwner){ owner = newOwner; }
   public void setParent(ProjectItem newParent){ parent = newParent; }
   public void setPrimaryTask(boolean newPrimaryTask){ primaryTask = newPrimaryTask; }
   public void setDetails(String newDetails){ details = newDetails; }
   
   public void addProjectItem(ProjectItem element){
       if (!projectItems.contains(element)){
           projectItems.add(element);
       }
   }
   
   public void removeProjectItem(ProjectItem element){
       projectItems.remove(element);
   }
   
   public String toString(){
       return name;
   }

} class DataCreator{

   private static final String DEFAULT_FILE = "data.ser";
   
   public static void main(String [] args){
       String fileName;
       if (args.length == 1){
           fileName = args[0];
       }
       else{
           fileName = DEFAULT_FILE;
       }
       serialize(fileName);
   }
   
   public static void serialize(String fileName){
       try{
           serializeToFile(createData(), fileName);
       }
       catch (IOException exc){
           exc.printStackTrace();
       }
   }
   
   private static Serializable createData(){
       Contact contact1 = new ContactImpl("Dennis", "Moore", "Managing Director", "Highway Man, LTD");
       Contact contact2 = new ContactImpl("Joseph", "Mongolfier", "High Flyer", "Lighter than Air Productions");
       Contact contact3 = new ContactImpl("Erik", "Njoll", "Nomad without Portfolio", "Nordic Trek, Inc.");
       Contact contact4 = new ContactImpl("Lemming", "", "Principal Investigator", "BDA");
       
       Project project = new Project("IslandParadise", "Acquire a personal island paradise", contact2);
       
       Task task1 = new Task(project, "Fortune", "Acquire a small fortune", contact4, true);
       Task task2 = new Task(project, "Isle", "Locate an island for sale", null, true);
       Task task3 = new Task(project, "Name", "Decide on a name for the island", contact3, false);
       project.addProjectItem(task1);
       project.addProjectItem(task2);
       project.addProjectItem(task3);
       
       Task task4 = new Task(task1, "Fortune1", "Use psychic hotline to predict winning lottery numbers", null, false);
       Task task5 = new Task(task1, "Fortune2", "Invest winnings to ensure 50% annual interest", contact1, true);
       Task task6 = new Task(task2, "Isle1", "Research whether climate is better in the Atlantic or Pacific", contact1, true);
       Task task7 = new Task(task2, "Isle2", "Locate an island for auction on EBay", null, false);
       Task task8 = new Task(task2, "Isle2a", "Negotiate for sale of the island", null, false);
       Task task9 = new Task(task3, "Name1", "Research every possible name in the world", null, true);
       Task task10 = new Task(task3, "Name2", "Eliminate any choices that are not coffee-related", contact4, false);
       task1.addProjectItem(task4);
       task1.addProjectItem(task5);
       task2.addProjectItem(task6);
       task2.addProjectItem(task7);
       task2.addProjectItem(task8);
       task3.addProjectItem(task9);
       task3.addProjectItem(task10);
       return project;
   }
   
   private static void serializeToFile(Serializable content, String fileName) throws IOException{
       ObjectOutputStream serOut = new ObjectOutputStream(new FileOutputStream(fileName));
       serOut.writeObject(content);
       serOut.close();
   }

} interface ProjectItem extends Serializable{

   public static final String EOL_STRING = System.getProperty("line.separator");
   public ProjectItem getParent();
   public Contact getOwner();
   public String getDetails();
   public ArrayList getProjectItems();

} class Project implements ProjectItem{

   private String name;
   private Contact owner;
   private String details;
   private ArrayList projectItems = new ArrayList();
   
   public Project(){ }
   public Project(String newName, String newDetails, Contact newOwner){
       name = newName;
       owner = newOwner;
       details = newDetails;
   }
   
   public String getName(){ return name; }
   public String getDetails(){ return details; }
   public Contact getOwner(){ return owner; }
   public ProjectItem getParent(){ return null; }
   public ArrayList getProjectItems(){ return projectItems; }
   
   public void setName(String newName){ name = newName; }
   public void setOwner(Contact newOwner){ owner = newOwner; }
   public void setDetails(String newDetails){ details = newDetails; }
   
   public void addProjectItem(ProjectItem element){
       if (!projectItems.contains(element)){
           projectItems.add(element);
       }
   }
   
   public void removeProjectItem(ProjectItem element){
       projectItems.remove(element);
   }
   
   public String toString(){
       return name;
   }

} class DataRetriever{

   public static Object deserializeData(String fileName){
       Object returnValue = null;
       try{
           File inputFile = new File(fileName);
           if (inputFile.exists() && inputFile.isFile()){
               ObjectInputStream readIn = new ObjectInputStream(new FileInputStream(fileName));
               returnValue = readIn.readObject();
               readIn.close();
           }
           else {
               System.err.println("Unable to locate the file " + fileName);
           }
       }
       catch (ClassNotFoundException exc){
           exc.printStackTrace();
           
       }
       catch (IOException exc){
           exc.printStackTrace();
           
       }
       return returnValue;
   }

}

      </source>