Java/Design Pattern/Template Pattern

Материал из Java эксперт
Перейти к: навигация, поиск

Template Method Pattern

   <source lang="java">

//[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; }

}


      </source>
   
  
 
  



Template pattern in Java

   <source lang="java">

/* The Design Patterns Java Companion Copyright (C) 1998, by James W. Cooper IBM Thomas J. Watson Research Center

  • /

import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JPanel; public class TriangleDrawing extends JFrame {

 stdTriangle t, t1;
 IsocelesTriangle it;
 public TriangleDrawing() {
   super("Draw triangles");
   addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   TPanel tp = new TPanel();
   t = new stdTriangle(new Point(10, 10), new Point(150, 50), new Point(
       100, 75));
   it = new IsocelesTriangle(new Point(150, 100), new Point(240, 40),
       new Point(175, 150));
   t1 = new stdTriangle(new Point(150, 100), new Point(240, 40),
       new Point(175, 150));
   tp.addTriangle(t);
   tp.addTriangle(it);
   // tp.addTriangle(t1);
   getContentPane().add(tp);
   setSize(300, 200);
   setBackground(Color.white);
   setVisible(true);
 }
 public static void main(String[] arg) {
   new TriangleDrawing();
 }

} class TPanel extends JPanel {

 Vector triangles;
 public TPanel() {
   triangles = new Vector();
 }
 public void addTriangle(Triangle t) {
   triangles.addElement(t);
 }
 public void paint(Graphics g) {
   for (int i = 0; i < triangles.size(); i++) {
     Triangle tngl = (Triangle) triangles.elementAt(i);
     tngl.draw(g);
   }
 }

} abstract class Triangle {

 Point p1, p2, p3;
 public Triangle(Point a, Point b, Point c) {
   //save
   p1 = a;
   p2 = b;
   p3 = c;
 }
 public void draw(Graphics g) {
   //This routine draws a general triangle
   drawLine(g, p1, p2);
   Point current = draw2ndLine(g, p2, p3);
   closeTriangle(g, current);
 }
 public void drawLine(Graphics g, Point a, Point b) {
   g.drawLine(a.x, a.y, b.x, b.y);
 }
 //this routine is the "Hook" that has to be implemented
 //for each triangle type.
 abstract public Point draw2ndLine(Graphics g, Point a, Point b);
 public void closeTriangle(Graphics g, Point c) {
   //draw back to first point
   g.drawLine(c.x, c.y, p1.x, p1.y);
 }

} class stdTriangle extends Triangle {

 public stdTriangle(Point a, Point b, Point c) {
   super(a, b, c);
 }
 public Point draw2ndLine(Graphics g, Point a, Point b) {
   g.drawLine(a.x, a.y, b.x, b.y);
   return b;
 }

} class IsocelesTriangle extends Triangle {

 Point newc;
 int newcx, newcy;
 int incr;
 public IsocelesTriangle(Point a, Point b, Point c) {
   super(a, b, c);
   double dx1 = b.x - a.x;
   double dy1 = b.y - a.y;
   double dx2 = c.x - b.x;
   double dy2 = c.y - b.y;
   double side1 = calcSide(dx1, dy1);
   double side2 = calcSide(dx2, dy2);
   if (side2 < side1)
     incr = -1;
   else
     incr = 1;
   double slope = dy2 / dx2;
   double intercept = c.y - slope * c.x;
   //move point c so that this is an isoceles triangle
   newcx = c.x;
   newcy = c.y;
   while (Math.abs(side1 - side2) > 1) {
     newcx += incr; //iterate a pixel at a time until close
     newcy = (int) (slope * newcx + intercept);
     dx2 = newcx - b.x;
     dy2 = newcy - b.y;
     side2 = calcSide(dx2, dy2);
   }
   newc = new Point(newcx, newcy);
 }
 //calculate length of side
 private double calcSide(double dx, double dy) {
   return Math.sqrt(dx * dx + dy * dy);
 }
 //draws 2nd line using saved new point
 public Point draw2ndLine(Graphics g, Point b, Point c) {
   g.drawLine(b.x, b.y, newc.x, newc.y);
   return newc;
 }

}

      </source>