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

Behavioral Pattern Code Examples

Chain of Responsibility

The PIM can act as a project manager as well as a contact manager. This code example shows how to use the Chain of Responsibility pattern to retrieve information from within a project hierarchy.

The ProjectItem interface defines common methods for anything that can be part of a project.

Example A.32 ProjectItem.java

1.import java.io.Serializable;

2.import java.util.ArrayList;

3.public interface ProjectItem extends Serializable{

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

5.public ProjectItem getParent();

6.public Contact getOwner();

7.public String getDetails();

8.public ArrayList getProjectItems();

9.}

The interface defines the methods getParent, getOwner, getDetails, and getProjectItems. Two classes implement ProjectItem in this example — Project and Task. The Project class is the base of a project, so its getParent method returns null. The getOwner and getDetails method returns the overall owner and details for the project, and the getProjectItems method returns all of the project’s immediate children.

Example A.33 Project.java

1.import java.util.ArrayList;

2.public class Project implements ProjectItem{

3.private String name;

4.private Contact owner;

5.private String details;

6.private ArrayList projectItems = new ArrayList();

8.public Project(){ }

9.public Project(String newName, String newDetails, Contact newOwner){

10.name = newName;

11.owner = newOwner;

12.details = newDetails;

13.}

14.

15.public String getName(){ return name; }

16.public String getDetails(){ return details; }

17.public Contact getOwner(){ return owner; }

18.public ProjectItem getParent(){ return null; }

19.public ArrayList getProjectItems(){ return projectItems; }

21.public void setName(String newName){ name = newName; }

22.public void setOwner(Contact newOwner){ owner = newOwner; }

23.public void setDetails(String newDetails){ details = newDetails; }

25.public void addProjectItem(ProjectItem element){

26.if (!projectItems.contains(element)){

27. projectItems.add(element);

28.}

29.}

31.public void removeProjectItem(ProjectItem element){

32.projectItems.remove(element);

33.}

34.

35.public String toString(){

36.return name;

37.}

38.}

The Task class represents some job associated with the project. Like Project, Task can keep a collection of subtasks, and its getProjectItems method will return these objects. For Task, the getParent method returns the parent, which will be another Task or the Project.

Example A.34 Task.java

238

1.import java.util.ArrayList;

2.import java.util.ListIterator;

3.public class Task implements ProjectItem{

4.private String name;

5.private ArrayList projectItems = new ArrayList();

6.private Contact owner;

7.private String details;

8.private ProjectItem parent;

9.private boolean primaryTask;

10.

11.public Task(ProjectItem newParent){

12.this(newParent, "", "", null, false);

13.}

14.public Task(ProjectItem newParent, String newName,

15.String newDetails, Contact newOwner, boolean newPrimaryTask){

16.

parent = newParent;

17.

name = newName;

18.

owner = newOwner;

19.

details = newDetails;

20.

primaryTask = newPrimaryTask;

21.

}

22.

 

23.public Contact getOwner(){

24.if (owner == null){

25. return parent.getOwner();

26.}

27.else{

28.

return owner;

29.}

30.}

32.public String getDetails(){

33.if (primaryTask){

34.

return details;

35.}

36.else{

37. return parent.getDetails() + EOL_STRING + "\t" + details;

38.}

39.}

41.public String getName(){ return name; }

42.public ArrayList getProjectItems(){ return projectItems; }

43.public ProjectItem getParent(){ return parent; }

44.public boolean isPrimaryTask(){ return primaryTask; }

45.

46.public void setName(String newName){ name = newName; }

47.public void setOwner(Contact newOwner){ owner = newOwner; }

48.public void setParent(ProjectItem newParent){ parent = newParent; }

49.public void setPrimaryTask(boolean newPrimaryTask){ primaryTask = newPrimaryTask; }

50.public void setDetails(String newDetails){ details = newDetails; }

51.

52.public void addProjectItem(ProjectItem element){

53.if (!projectItems.contains(element)){

54. projectItems.add(element);

55.}

56.}

58.public void removeProjectItem(ProjectItem element){

59.projectItems.remove(element);

60.}

61.

62.public String toString(){

63.return name;

64.}

65.}

The Chain of Responsibility behavior is manifested in the getOwner and getDetails methods of Task. For getOwner, a Task will either return its internally referenced owner (if non-null), or that of its parent. If the parent was a Task and its owner was null as well, the method call is passed on to the next parent until it eventually encountered a non-null owner or it reaches the Project itself. This makes it easy to set up a group of Tasks where the same individual is the designated owner, responsible for the completion of a Task and all subtasks of

Tasks.

The getDetails method is another example of Chain of Responsibility behavior, but it behaves somewhat differently. It calls the getDetails method of each parent until it reaches a Task or Project that is identified as

239

a terminal node. This means that getDetails returns a series of Strings representing all the details for a particular Task chain.

Support classes for the example include the Contact interface and ContactImpl class, which are used by Project and

Task to define an owner.

Example A.35 Contact.java

1.import java.io.Serializable;

2.public interface Contact extends Serializable{

3.public static final String SPACE = " ";

4.public String getFirstName();

5.public String getLastName();

6.public String getTitle();

7.public String getOrganization();

8.

9.public void setFirstName(String newFirstName);

10.public void setLastName(String newLastName);

11.public void setTitle(String newTitle);

12.public void setOrganization(String newOrganization);

13.}

Example A.36 ContactImpl.java

1.public class ContactImpl implements Contact{

2.private String firstName;

3.private String lastName;

4.private String title;

5.private String organization;

6.

7.public ContactImpl(){}

8.public ContactImpl(String newFirstName, String newLastName,

9.String newTitle, String newOrganization){

10. firstName = newFirstName;

11. lastName = newLastName;

12. title = newTitle;

13. organization = newOrganization;

14. }

15.

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

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

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

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

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

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

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

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

26.public String toString(){

27.return firstName + SPACE + lastName;

28.}

29.}

The DataCreator class provide support classes to generate data and serialize it to a file, while the DataRetriever class retrieves the data for use in the example. The RunPattern class coordinates between the other classes in the example, getting a project, then retrieving the owner and details for each Task and for the

Project itself.

Example A.37 DataCreator.java

1.import java.io.Serializable;

2.import java.io.ObjectOutputStream;

3.import java.io.FileOutputStream;

4.import java.io.IOException;

5.

6.public class DataCreator{

7.private static final String DEFAULT_FILE = "data.ser";

9.public static void main(String [] args){

10.String fileName;

11.if (args.length == 1){

12. fileName = args[0];

13.}

14.else{

15. fileName = DEFAULT_FILE;

240

16.}

17.serialize(fileName);

18.}

19.

20.public static void serialize(String fileName){

21.try {

22. serializeToFile(createData(), fileName);

23.}

24.catch (IOException exc){

25. exc.printStackTrace();

26.}

27.}

29.private static Serializable createData(){

30.Contact contact1 = new ContactImpl("Dennis", "Moore", "Managing Director", "Highway

Man, LTD");

31.Contact contact2 = new ContactImpl("Joseph", "Mongolfier", "High Flyer","Lighter

than Air Productions");

32.Contact contact3 = new ContactImpl("Erik", "Njoll", "Nomad without Portfolio",

"Nordic Trek, Inc.");

33. Contact contact4 = new ContactImpl("Lemming", "", "Principal Investigator", "BDA"); 34.

35.Project project = new Project("IslandParadise", "Acquire a personal island paradise",

contact2);

36.

37.Task task1 = new Task(project, "Fortune", "Acquire a small fortune", contact4, true);

38.Task task2 = new Task(project, "Isle", "Locate an island for sale", null, true);

39.Task task3 = new Task(project, "Name", "Decide on a name for the island", contact3,

false);

40.project.addProjectItem(task1);

41.project.addProjectItem(task2);

42.project.addProjectItem(task3);

44.Task task4 = new Task(task1, "Fortune1", "Use psychic hotline to predict winning

lottery numbers", null, false);

45.Task task5 = new Task(task1, "Fortune2", "Invest winnings to ensure 50% annual

interest", contact1, true);

46.Task task6 = new Task(task2, "Isle1", "Research whether climate is better in the

 

 

Y

47.

Atlantic or Pacific", contact1, true);

Task task7 = new Task(task2, "Isle2", "Locate an island for auction on EBay", null,

 

false);

L

48.Task task8 = new Task(task2, "Isle2a", "Negotiate for sale of the island", null,

false);

F

M

49.Task task9 = new Task(task3, "Name1", "Research every possible name in the world",

null, true);

50.Task task10 = new Task(task3, "Name2", "Eliminate any choices that are notE

 

T

51.

coffee-related", contact4, false);

task1.addProjectItem(task4);

52.

task1.addProjectItem(task5);

53.

task2.addProjectItem(task6);

54.

task2.addProjectItem(task7);

55.

task2.addProjectItem(task8);

56.

task3.addProjectItem(task9);

57.

task3.addProjectItem(task10);

58.

return project;

59.

}

60.

 

61.private static void serializeToFile(Serializable content, String fileName) throws

IOException {

62.ObjectOutputStream serOut = new ObjectOutputStream(new FileOutputStream(fileName));

63.serOut.writeObject(content);

64.serOut.close();

65.}

66.}

Example A.38 DataRetriever.java

1.import java.io.File;

2.import java.io.FileInputStream;

3.import java.io.IOException;

4.import java.io.ObjectInputStream;

6.public class DataRetriever{

7.public static Object deserializeData(String fileName){

8.Object returnValue = null;

9.try{

10. File inputFile = new File(fileName);TEAM FLY PRESENTS

11. if (inputFile.exists() && inputFile.isFile()){

241