//[C] 2002 Sun Microsystems, Inc.---
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
public class RunTemplateMethodPattern {
public static void main(String [] arguments){
System.out.println("Example for the Template Method pattern");
System.out.println("This code demonstrates how the template method can");
System.out.println(" be used to define a variable implementation for a");
System.out.println(" common operation. In this case, the ProjectItem");
System.out.println(" abstract class defines the method getCostEstimate,");
System.out.println(" which is a combination of the cost for time and");
System.out.println(" materials. The two concrete subclasses used here,");
System.out.println(" Task and Deliverable, have different methods of");
System.out.println(" providing a cost estimate.");
System.out.println();
System.out.println("Creating a demo Task and Deliverable");
System.out.println();
Task primaryTask = new Task("Put a JVM on the moon", "Lunar mission as part of the JavaSpace program ;)", 240.0, 100.0);
primaryTask.addProjectItem(new Task("Establish ground control", "", 1000.0, 10.0));
primaryTask.addProjectItem(new Task("Train the Javanaughts", "", 80.0, 30.0));
Deliverable deliverableOne = new Deliverable("Lunar landing module", "Ask the local garage if they can make a few minor modifications to one of their cars", 2800, 40.0, 35.0);
System.out.println("Calculating the cost estimates using the Template Method, getCostEstimate.");
System.out.println();
System.out.println("Total cost estimate for: " + primaryTask);
System.out.println("\t" + primaryTask.getCostEstimate());
System.out.println();
System.out.println("Total cost estimate for: " + deliverableOne);
System.out.println("\t" + deliverableOne.getCostEstimate());
}
}
abstract class ProjectItem implements Serializable{
private String name;
private String description;
private double rate;
public ProjectItem(){}
public ProjectItem(String newName, String newDescription, double newRate){
name = newName;
description = newDescription;
rate = newRate;
}
public void setName(String newName){ name = newName; }
public void setDescription(String newDescription){ description = newDescription; }
public void setRate(double newRate){ rate = newRate; }
public String getName(){ return name; }
public String getDescription(){ return description; }
public final double getCostEstimate(){
return getTimeRequired() * getRate() + getMaterialsCost();
}
public double getRate(){ return rate; }
public String toString(){ return getName(); }
public abstract double getTimeRequired();
public abstract double getMaterialsCost();
}
class Task extends ProjectItem{
private ArrayList projectItems = new ArrayList();
private double taskTimeRequired;
public Task(){ }
public Task(String newName, String newDescription,
double newTaskTimeRequired, double newRate){
super(newName, newDescription, newRate);
taskTimeRequired = newTaskTimeRequired;
}
public void setTaskTimeRequired(double newTaskTimeRequired){ taskTimeRequired = newTaskTimeRequired; }
public void addProjectItem(ProjectItem element){
if (!projectItems.contains(element)){
projectItems.add(element);
}
}
public void removeProjectItem(ProjectItem element){
projectItems.remove(element);
}
public double getTaskTimeRequired(){ return taskTimeRequired; }
public Iterator getProjectItemIterator(){ return projectItems.iterator(); }
public double getMaterialsCost(){
double totalCost = 0;
Iterator items = getProjectItemIterator();
while (items.hasNext()){
totalCost += ((ProjectItem)items.next()).getMaterialsCost();
}
return totalCost;
}
public double getTimeRequired(){
double totalTime = taskTimeRequired;
Iterator items = getProjectItemIterator();
while (items.hasNext()){
totalTime += ((ProjectItem)items.next()).getTimeRequired();
}
return totalTime;
}
}
class Deliverable extends ProjectItem{
private double materialsCost;
private double productionTime;
public Deliverable(){ }
public Deliverable(String newName, String newDescription,
double newMaterialsCost, double newProductionTime,
double newRate){
super(newName, newDescription, newRate);
materialsCost = newMaterialsCost;
productionTime = newProductionTime;
}
public void setMaterialsCost(double newCost){ materialsCost = newCost; }
public void setProductionTime(double newTime){ productionTime = newTime; }
public double getMaterialsCost(){ return materialsCost; }
public double getTimeRequired(){ return productionTime; }
}