Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Applied Java™ Patterns - Stephen Stelting, Olav Maassen.pdf
Скачиваний:
202
Добавлен:
24.05.2014
Размер:
2.84 Mб
Скачать

41.

state.equals(address.state) &&

42.

zipCode.equals(address.zipCode)){

43.

return true;

44.

}

45.

return false;

46.}

47.}

49.public String toString(){

50.return street + EOL_STRING + city + COMMA + SPACE +

51. state + SPACE + zipCode + EOL_STRING;

52.}

53.}

Example A.212 Contact.java

1.import java.io.Serializable;

2.import java.util.ArrayList;

3.public interface Contact extends Serializable{

4.public static final String SPACE = " ";

5.public static final String EOL_STRING = System.getProperty("line.separator");

6.public String getFirstName();

7.public String getLastName();

8.public String getTitle();

9.public String getOrganization();

10.public ArrayList getAddresses();

11.

12.public void setFirstName(String newFirstName);

13.public void setLastName(String newLastName);

14.public void setTitle(String newTitle);

15.public void setOrganization(String newOrganization);

16.public void addAddress(Address address);

17.public void removeAddress(Address address);

18.}

Example A.213 ContactImpl.java

1.import java.util.ArrayList;

2.public class ContactImpl implements Contact{

3.private String firstName;

4.private String lastName;

5.private String title;

6.private String organization;

7.private ArrayList addresses = new ArrayList();

9.public ContactImpl(){}

10.public ContactImpl(String newFirstName, String newLastName,

11.String newTitle, String newOrganization, ArrayList newAddresses){

12.firstName = newFirstName;

13.lastName = newLastName;

14.title = newTitle;

15.organization = newOrganization;

16.if (newAddresses != null){ addresses = newAddresses; }

17.}

18.

19.public String getFirstName(){ return firstName; }

20.public String getLastName(){ return lastName; }

21.public String getTitle(){ return title; }

22.public String getOrganization(){ return organization; }

23.public ArrayList getAddresses(){ return addresses; }

25.public void setFirstName(String newFirstName){ firstName = newFirstName; }

26.public void setLastName(String newLastName){ lastName = newLastName; }

27.public void setTitle(String newTitle){ title = newTitle; }

28.public void setOrganization(String newOrganization){ organization = newOrganization; }

29.public void addAddress(Address address){

30.if(!addresses.contains(address)){

31. addresses.add(address);

32.}

33.}

34.public void removeAddress(Address address){

35.addresses.remove(address);

36.}

37.

38.public boolean equals(Object o){

39.if (!(o instanceof ContactImpl)){

40.

return false;

41.}

335

42.else{

43.

ContactImpl contact = (ContactImpl)o;

44.

if (firstName.equals(contact.firstName) &&

45.

lastName.equals(contact.lastName) &&

46.

organization.equals(contact.organization) &&

47.

title.equals(contact.title)){

48.

return true;

49.

}

50.

return false;

51.}

52.}

54.public String toString(){

55.return firstName + SPACE + lastName + EOL_STRING + addresses;

56.}

57.}

RunPattern demonstrates how sessions can be used for communication between clients and servers. The main method creates a server and two clients, and subsequently uses both clients to make edits on Contact objects, adding and removing Address objects.

Example A.214 RunPattern.java

1.import java.io.IOException;

2.public class RunPattern{

3.public static void main(String [] arguments){

4.System.out.println("Example for the Session pattern");

5.System.out.println("This demonstration will show how a Session can be used");

6.System.out.println(" to organize a series of actions between a client and");

7.System.out.println(" server.");

8.System.out.println("In this case, clients will use sessions to coordinate");

9.System.out.println(" edits of Contact addresses.");

10.System.out.println();

11.

12.System.out.println("Running the RMI compiler (rmic)");

13.System.out.println();

14.try{

15. Process p1 = Runtime.getRuntime().exec("rmic SessionServerImpl");

16. p1.waitFor();

17.}

18.catch (IOException exc){

19.System.err.println("Unable to run rmic utility. Exiting application.");

20. System.exit(1);

21.}

22.catch (InterruptedException exc){

23.System.err.println("Threading problems encountered while using the rmic utility.");

24.}

25.

26.System.out.println("Starting the rmiregistry");

27.System.out.println();

28.Process rmiProcess = null;

29.try{

30.rmiProcess = Runtime.getRuntime().exec("rmiregistry");

31.Thread.sleep(15000);

32.}

33.catch (IOException exc){

34.System.err.println("Unable to start the rmiregistry. Exiting application.");

35.System.exit(1);

36.}

37.catch (InterruptedException exc){

38.System.err.println("Threading problems encountered when starting the rmiregistry.");

39.}

40.

41.System.out.println("Creating the SessionServer and two SessionClient objects");

42.System.out.println();

43.SessionServer serverObject = new SessionServerImpl();

44.SessionClient clientOne = new SessionClient();

45.SessionClient clientTwo = new SessionClient();

46.

47.System.out.println("Creating sample Contacts and Addresses");

48.System.out.println();

49.Contact firstContact = new ContactImpl("First", "Contact", "primo", "OOI", null);

50.Contact secondContact = new ContactImpl("Second", "Contact", "secondo", "OOI", null);

51.Address workAddress = new AddressImpl("Work address", "5440 Division", "Fargo", "ND",

"54321");

52.Address homeAddress = new AddressImpl("Home address", "40 Planar Way", "Paris", "TX",

"84301");

336

53.

54.System.out.println("Adding a contact. Both clients will attempt to edit");

55.System.out.println(" the same contact at first, which will result in a");

56.System.out.println(" SessionException.");

57.try {

58.clientOne.addContact(firstContact);

59.clientTwo.addContact(firstContact);

60.}

61.catch (SessionException exc){

62.System.err.println("Exception encountered:");

63.System.err.println(exc);

64.}

65.try {

66.System.out.println("Adding a different contact to the second client");

67.clientTwo.addContact(secondContact);

68.System.out.println("Adding addresses to the first and second clients");

69.clientTwo.addAddress(workAddress);

70.clientOne.addAddress(homeAddress);

71.clientTwo.addAddress(workAddress);

72.clientTwo.addAddress(homeAddress);

73.System.out.println("Removing address from a client");

74.clientTwo.removeAddress(homeAddress);

75.System.out.println("Finalizing the edits to the contacts");

76.clientOne.commitChanges();

77.clientTwo.commitChanges();

78.System.out.println("Changes finalized");

79.clientTwo.addContact(firstContact);

80.}

81.catch (SessionException exc){

82.System.err.println("Exception encountered:");

83.System.err.println(exc);

84.}

85.System.out.println("The following lines will show the state");

86.System.out.println(" of the server-side delegate, which in this");

87.System.out.println(" example represents a persistent data store.");

88.System.out.println();

89.System.out.println("Contact list:");

90.System.out.println(SessionServerDelegate.getContacts());

91.System.out.println("Address list:");

92.System.out.println(SessionServerDelegate.getAddresses());

93.System.out.println("Edit contacts:");

94.System.out.println(SessionServerDelegate.getEditContacts());

95.}

96.}

337

Worker Thread

In a typical application, certain jobs have to be done. It's not always important that they happen now, just that they do happen. You can compare this to cleaning a house. It's not important that it happen at a particular time, as long as somebody does it sometime this week—or month, or year, depending on your standards.

This example uses a Queue to hold tasks. The Queue interface defines two basic methods, put and take. These methods are used to add and remove tasks, represented by the RunnableTask interface, on the Queue.

Example A.215 Queue.java

1.public interface Queue{

2.void put(RunnableTask r);

3.RunnableTask take();

4.}

Example A.216 RunnableTask.java

1.public interface RunnableTask{

2.public void execute();

3.}

The ConcreteQueue class implements the Queue and provides a worker thread to operate on the RunnableTask objects. The inner class defined for ConcreteQueue, Worker, has a run method that continually searches the queue for new tasks to perform. When a task becomes available, the worker thread pops the RunnableTask off the queue and runs its execute method.

Example A.217 ConcreteQueue.java

1.import java.util.Vector;

2.public class ConcreteQueue implements Queue{

3.private Vector tasks = new Vector();

4.private boolean waiting;

5.private boolean shutdown;

6.

7. public void setShutdown(boolean isShutdown){ shutdown = isShutdown; }

8.

9.public ConcreteQueue(){

10.tasks = new Vector();

11.waiting = false;

12.new Thread(new Worker()).start();

13.}

14.

15.public void put(RunnableTask r){

16.tasks.add(r);

17.if (waiting){

18.

synchronized (this){

19.

notifyAll();

20.

}

21.}

22.}

24.public RunnableTask take(){

25.if (tasks.isEmpty()){

26.

synchronized (this){

27.

waiting = true;

28.

try{

29.

wait();

30.

} catch (InterruptedException ie){

31.

waiting = false;

32.

}

33.

}

34.}

35.return (RunnableTask)tasks.remove(0);

36.}

37.

38.private class Worker implements Runnable{

39.public void run(){

40.

while (!shutdown){

41.

RunnableTask r = take();

42.

r.execute();

43.

}

44.}

45.}

338