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

60.return project;

61.}

62.

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

IOException {

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

65.serOut.writeObject(content);

66.serOut.close();

67.}

68.}

The DataRetriever class provides a resource to deserialize an object from a file with the deserializeData method.

Example A.152 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);

11.

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

12.

ObjectInputStream readIn = new ObjectInputStream(new FileInputStream(fileName));

13.

returnValue = readIn.readObject();

14.

readIn.close();

15.

}else{

16.

System.err.println("Unable to locate the file " + fileName);

17.

}

18.}catch (ClassNotFoundException exc){

19.

exc.printStackTrace();

20.

 

21.}catch (IOException exc){

22. exc.printStackTrace();

23.}

24.return returnValue;

25.}

26.}

The RunPattern class uses DataRetriever to deserialize the project, then calls the getTimeRequired method to calculate the time requirements for the entire project.

Example A.153 RunPattern.java

1.import java.io.File;

2.public class RunPattern{

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

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

5.System.out.println();

6.System.out.println("This code sample will propagate a method call throughout");

7.System.out.println(" a tree structure. The tree represents a project, and is");

8.System.out.println(" composed of three kinds of ProjectItems - Project, Task,");

9.System.out.println(" and Deliverable. Of these three classes, Project and Task");

10.System.out.println(" can store an ArrayList of ProjectItems. This means that");

11.System.out.println(" they can act as branch nodes for our tree. The Deliverable");

12.System.out.println(" is a terminal node, since it cannot hold any ProjectItems.");

13.System.out.println();

14.System.out.println("In this example, the method defined by ProjectItem,");

15.System.out.println(" getTimeRequired, provides the method to demonstrate the");

16.System.out.println(" pattern. For branch nodes, the method will be passed on");

17.System.out.println(" to the children. For terminal nodes (Deliverables), a");

18.System.out.println(" single value will be returned.");

19.System.out.println();

20.System.out.println("Note that it is possible to make this method call ANYWHERE");

21.System.out.println(" in the tree, since all classes implement the getTimeRequired");

22.System.out.println(" method. This means that you are able to calculate the time");

23.System.out.println(" required to complete the whole project OR any part of it.");

24.System.out.println();

25.

26.System.out.println("Deserializing a test Project for the Composite pattern");

27.System.out.println();

28.if (!(new File("data.ser").exists())){

29. DataCreator.serialize("data.ser");

300

30.}

31.Project project = (Project)(DataRetriever.deserializeData("data.ser"));

33.System.out.println("Calculating total time estimate for the project");

34.System.out.println("\t" + project.getDescription());

35.System.out.println("Time Required: " + project.getTimeRequired());

36.

37.}

38.}

 

 

Y

 

 

L

 

 

F

 

 

M

 

A

E

 

T

 

 

TEAM FLY PRESENTS

301

Decorator

This example demonstrates how to use the Decorator pattern to extend the capability of the elements in a project. The foundation of the project is the ProjectItem interface. It is implemented by any class that can be used within a project. In this case, ProjectItem defines a single method, getTimeRequired.

Example A.154 ProjectItem.java

1.import java.io.Serializable;

2.public interface ProjectItem extends Serializable{

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

4.public double getTimeRequired();

5.}

Task and Deliverable implement ProjectItem and provide the basic project functionality. As in previous demonstrations, Task represents some job in a project and Deliverable represents some concrete product.

Example A.155 Deliverable.java

1.public class Deliverable implements ProjectItem{

2.private String name;

3.private String description;

4.private Contact owner;

5.

6.public Deliverable(){ }

7.public Deliverable(String newName, String newDescription,

8.Contact newOwner){

9.name = newName;

10.description = newDescription;

11.owner = newOwner;

12.}

13.

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

15.public String getDescription(){ return description; }

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

17.public double getTimeRequired(){ return 0; }

18.

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

20.public void setDescription(String newDescription){ description = newDescription; }

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

22.

23.public String toString(){

24.return "Deliverable: " + name;

25.}

26.}

Example A.156 Task.java

1.import java.util.ArrayList;

2.import java.util.Iterator;

3.public class Task implements ProjectItem{

4.private String name;

5.private ArrayList projectItems = new ArrayList();

6.private Contact owner;

7.private double timeRequired;

8.

9.public Task(){ }

10.public Task(String newName, Contact newOwner,

11.double newTimeRequired){

12.name = newName;

13.owner = newOwner;

14.timeRequired = newTimeRequired;

15.}

16.

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

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

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

20.public double getTimeRequired(){

21.double totalTime = timeRequired;

22.Iterator items = projectItems.iterator();

23.while(items.hasNext()){

24. ProjectItem item = (ProjectItem)items.next();

25. totalTime += item.getTimeRequired();

26.}

27.return totalTime;

302

28. }

29.

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

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

32.public void setTimeRequired(double newTimeRequired){ timeRequired = newTimeRequired; }

34.public void addProjectItem(ProjectItem element){

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

36. projectItems.add(element);

37.}

38.}

39.public void removeProjectItem(ProjectItem element){

40.projectItems.remove(element);

41.}

42.

43.public String toString(){

44.return "Task: " + name;

45.}

46.}

It's time to introduce a decorator to extend the basic capabilities of these classes. The class ProjectDecorator will provide the central ability to augment Task and Deliverable.

Example A.157 ProjectDecorator.java

1.public abstract class ProjectDecorator implements ProjectItem{

2.private ProjectItem projectItem;

3.

4.protected ProjectItem getProjectItem(){ return projectItem; }

5.public void setProjectItem(ProjectItem newProjectItem){ projectItem = newProjectItem; }

7.public double getTimeRequired(){

8.return projectItem.getTimeRequired();

9.}

10.}

The ProjectDecorator implements the ProjectItem interface and maintains a variable for another ProjectItem, which represents the “decorated” element. Note that ProjectDecorator delegates the getTimeRequired method to its internal element. This would be done for any method that would depend on the functionality of the underlying component. If a Task with a required time of five days were decorated, you would still expect it to return a value of five days, regardless of any other capabilities it might have.

There are two subclasses of ProjectDecorator in this example. Both demonstrate a way to add some extra feature to project elements. The DependentProjectItem class is used to show that a Task or Deliverable depends on another ProjectItem for completion.

Example A.158 DependentProjectItem.java

1.public class DependentProjectItem extends ProjectDecorator{

2.private ProjectItem dependentItem;

3.

4.public DependentProjectItem(){ }

5.public DependentProjectItem(ProjectItem newDependentItem){

6.dependentItem = newDependentItem;

7.}

8.

9. public ProjectItem getDependentItem(){ return dependentItem; }

10.

11.public void setDependentItem(ProjectItem newDependentItem){ dependentItem =

newDependentItem; }

12.

13.public String toString(){

14.return getProjectItem().toString() + EOL_STRING

15. + "\tProjectItem dependent on: " + dependentItem;

16.}

17.}

SupportedProjectItem decorates a ProjectItem, and keeps an ArrayList of supporting documents—file objects that represent additional information or resources.

Example A.159 SupportedProjectItem.java

1.import java.util.ArrayList;

2.import java.io.File;

303