Java/Design Pattern/Template Pattern

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

Template Method Pattern

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





Template pattern in 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;
  }
}