Java/Design Pattern/Call Back Pattern
Версия от 18:01, 31 мая 2010; (обсуждение)
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;
}
}