Java/Design Pattern/Call Back Pattern

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

Callback Pattern in 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();
}





Chain Pattern

//[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;
    }
}