Java/Design Pattern/Decorator Pattern

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

Decorator Design Pattern in Java

/*
Software Architecture Design Patterns in Java
by Partha Kuchana 
Auerbach Publications
*/
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.Vector;
public class DecoratorClient {
  public static void main(String[] args) {
    LoggerFactory factory = new LoggerFactory();
    Logger logger = factory.getLogger();
    HTMLLogger hLogger = new HTMLLogger(logger);
    //the decorator object provides the same interface.
    hLogger.log("A Message to Log");
    EncryptLogger eLogger = new EncryptLogger(logger);
    eLogger.log("A Message to Log");
  }
} // End of class
class ConsoleLogger implements Logger {
  public void log(String msg) {
    System.out.println(msg);
  }
}
class MiscUtil {
  public static boolean hasDuplicates(Vector v) {
    int i = 0;
    int j = 0;
    boolean duplicates = false;
    for (i = 0; i < v.size() - 1; i++) {
      for (j = (i + 1); j < v.size(); j++) {
        if (v.elementAt(i).toString().equalsIgnoreCase(
            v.elementAt(j).toString())) {
          duplicates = true;
        }
      }
    }
    return duplicates;
  }
  public static Vector removeDuplicates(Vector s) {
    int i = 0;
    int j = 0;
    boolean duplicates = false;
    Vector v = new Vector();
    for (i = 0; i < s.size(); i++) {
      duplicates = false;
      for (j = (i + 1); j < s.size(); j++) {
        if (s.elementAt(i).toString().equalsIgnoreCase(
            s.elementAt(j).toString())) {
          duplicates = true;
        }
      }
      if (duplicates == false) {
        v.addElement(s.elementAt(i).toString().trim());
      }
    }
    return v;
  }
  public static Vector removeDuplicateDomains(Vector s) {
    int i = 0;
    int j = 0;
    boolean duplicates = false;
    String str1 = "";
    String str2 = "";
    Vector v = new Vector();
    for (i = 0; i < s.size(); i++) {
      duplicates = false;
      for (j = (i + 1); j < s.size(); j++) {
        str1 = "";
        str2 = "";
        str1 = s.elementAt(i).toString().trim();
        str2 = s.elementAt(j).toString().trim();
        if (str1.indexOf("@") > -1) {
          str1 = str1.substring(str1.indexOf("@"));
        }
        if (str2.indexOf("@") > -1) {
          str2 = str2.substring(str2.indexOf("@"));
        }
        if (str1.equalsIgnoreCase(str2)) {
          duplicates = true;
        }
      }
      if (duplicates == false) {
        v.addElement(s.elementAt(i).toString().trim());
      }
    }
    return v;
  }
  public static boolean areVectorsEqual(Vector a, Vector b) {
    if (a.size() != b.size()) {
      return false;
    }
    int i = 0;
    int vectorSize = a.size();
    boolean identical = true;
    for (i = 0; i < vectorSize; i++) {
      if (!(a.elementAt(i).toString().equalsIgnoreCase(b.elementAt(i)
          .toString()))) {
        identical = false;
      }
    }
    return identical;
  }
  public static Vector removeDuplicates(Vector a, Vector b) {
    int i = 0;
    int j = 0;
    boolean present = true;
    Vector v = new Vector();
    for (i = 0; i < a.size(); i++) {
      present = false;
      for (j = 0; j < b.size(); j++) {
        if (a.elementAt(i).toString().equalsIgnoreCase(
            b.elementAt(j).toString())) {
          present = true;
        }
      }
      if (!(present)) {
        v.addElement(a.elementAt(i));
      }
    }
    return v;
  }
}// end of class
class LoggerDecorator implements Logger {
  Logger logger;
  public LoggerDecorator(Logger inp_logger) {
    logger = inp_logger;
  }
  public void log(String DataLine) {
    /*
     * Default implementation to be overriden by subclasses.
     */
    logger.log(DataLine);
  }
}// end of class
interface Logger {
  public void log(String msg);
}
class HTMLLogger extends LoggerDecorator {
  public HTMLLogger(Logger inp_logger) {
    super(inp_logger);
  }
  public void log(String DataLine) {
    /*
     * Added functionality
     */
    DataLine = makeHTML(DataLine);
    /*
     * Now forward the encrypted text to the FileLogger for storage
     */
    logger.log(DataLine);
  }
  public String makeHTML(String DataLine) {
    /*
     * Make it into an HTML document.
     */
    DataLine = "<HTML><BODY>" + "<b>" + DataLine + "</b>"
        + "</BODY></HTML>";
    return DataLine;
  }
}// end of class
class FileUtil {
  DataOutputStream dos;
  /*
   * Utility method to write a given text to a file
   */
  public boolean writeToFile(String fileName, String dataLine,
      boolean isAppendMode, boolean isNewLine) {
    if (isNewLine) {
      dataLine = "\n" + dataLine;
    }
    try {
      File outFile = new File(fileName);
      if (isAppendMode) {
        dos = new DataOutputStream(new FileOutputStream(fileName, true));
      } else {
        dos = new DataOutputStream(new FileOutputStream(outFile));
      }
      dos.writeBytes(dataLine);
      dos.close();
    } catch (FileNotFoundException ex) {
      return (false);
    } catch (IOException ex) {
      return (false);
    }
    return (true);
  }
  /*
   * Reads data from a given file
   */
  public String readFromFile(String fileName) {
    String DataLine = "";
    try {
      File inFile = new File(fileName);
      BufferedReader br = new BufferedReader(new InputStreamReader(
          new FileInputStream(inFile)));
      DataLine = br.readLine();
      br.close();
    } catch (FileNotFoundException ex) {
      return (null);
    } catch (IOException ex) {
      return (null);
    }
    return (DataLine);
  }
  public boolean isFileExists(String fileName) {
    File file = new File(fileName);
    return file.exists();
  }
  public boolean deleteFile(String fileName) {
    File file = new File(fileName);
    return file.delete();
  }
  /*
   * Reads data from a given file into a Vector
   */
  public Vector fileToVector(String fileName) {
    Vector v = new Vector();
    String inputLine;
    try {
      File inFile = new File(fileName);
      BufferedReader br = new BufferedReader(new InputStreamReader(
          new FileInputStream(inFile)));
      while ((inputLine = br.readLine()) != null) {
        v.addElement(inputLine.trim());
      }
      br.close();
    } // Try
    catch (FileNotFoundException ex) {
      //
    } catch (IOException ex) {
      //
    }
    return (v);
  }
  /*
   * Writes data from an input vector to a given file
   */
  public void vectorToFile(Vector v, String fileName) {
    for (int i = 0; i < v.size(); i++) {
      writeToFile(fileName, (String) v.elementAt(i), true, true);
    }
  }
  /*
   * Copies unique rows from a source file to a destination file
   */
  public void copyUniqueElements(String sourceFile, String resultFile) {
    Vector v = fileToVector(sourceFile);
    v = MiscUtil.removeDuplicates(v);
    vectorToFile(v, resultFile);
  }
} // end FileUtil
class FileLogger implements Logger {
  private static FileLogger logger;
  //Prevent clients from using the constructor
  private FileLogger() {
  }
  public static FileLogger getFileLogger() {
    if (logger == null) {
      logger = new FileLogger();
    }
    return logger;
  }
  public synchronized void log(String msg) {
    FileUtil futil = new FileUtil();
    futil.writeToFile("log.txt", msg, true, true);
  }
}
class EncryptLogger extends LoggerDecorator {
  public EncryptLogger(Logger inp_logger) {
    super(inp_logger);
  }
  public void log(String DataLine) {
    /*
     * Added functionality
     */
    DataLine = encrypt(DataLine);
    /*
     * Now forward the encrypted text to the FileLogger for storage
     */
    logger.log(DataLine);
  }
  public String encrypt(String DataLine) {
    /*
     * Apply simple encryption by Transposition... Shift all characters by
     * one position.
     */
    DataLine = DataLine.substring(DataLine.length() - 1)
        + DataLine.substring(0, DataLine.length() - 1);
    return DataLine;
  }
}// end of class
class LoggerFactory {
  public boolean isFileLoggingEnabled() {
    Properties p = new Properties();
    try {
      p.load(ClassLoader.getSystemResourceAsStream("Logger.properties"));
      String fileLoggingValue = p.getProperty("FileLogging");
      if (fileLoggingValue.equalsIgnoreCase("ON") == true)
        return true;
      else
        return false;
    } catch (IOException e) {
      return false;
    }
  }
  public Logger getLogger() {
    if (isFileLoggingEnabled()) {
      return FileLogger.getFileLogger();
    } else {
      return new ConsoleLogger();
    }
  }
}





Decorator Pattern 1

//[C] 2002 Sun Microsystems, Inc.---
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
public class RunDecoratorPattern {
    public static void main(String [] arguments){
        System.out.println("Example for the Decorator pattern");
        System.out.println();
        System.out.println("This demonstration will show how Decorator classes can be used");
        System.out.println(" to extend the basic functionality of ProjectItems. The Task and");
        System.out.println(" Deliverable classes provide the basic ProjectItems, and their");
        System.out.println(" functionality will be extended by adding subclasses of the");
        System.out.println(" abstract class ProjectDecorator.");
        System.out.println();
        System.out.println("Note that the toString method has been overridden for all ProjectItems,");
        System.out.println(" to more effectively show how Decorators are associated with their");
        System.out.println(" ProjectItems.");
        System.out.println();
        
        System.out.println("Creating ProjectItems.");
        Contact contact1 = new ContactImpl("Simone", "Roberto", "Head Researcher and Chief Archivist", "Institute for Advanced (Java) Studies");
        Task task1 = new Task("Perform months of diligent research", contact1, 20.0);
        Task task2 = new Task("Obtain grant from World Java Foundation", contact1, 40.0);
        Deliverable deliverable1 = new Deliverable("Java History", "Comprehensive history of the design of all Java APIs", contact1);
        System.out.println("ProjectItem objects created. Results:");
        System.out.println(task1);
        System.out.println(task2);
        System.out.println(deliverable1);
        System.out.println();
        
        System.out.println("Creating decorators");
        ProjectDecorator decorator1 = new SupportedProjectItem(new File("JavaHistory.txt"));
        ProjectDecorator decorator2 = new DependentProjectItem(task2);
        System.out.println("Decorators created. Adding decorators to the first task");
        decorator1.setProjectItem(task1);
        decorator2.setProjectItem(decorator1);
        System.out.println();
        System.out.println("Decorators added. Results");
        System.out.println(decorator2);
        
        System.out.println("");
    }
}
interface Contact extends Serializable{
    public static final String SPACE = " ";
    public String getFirstName();
    public String getLastName();
    public String getTitle();
    public String getOrganization();
    
    public void setFirstName(String newFirstName);
    public void setLastName(String newLastName);
    public void setTitle(String newTitle);
    public void setOrganization(String newOrganization);
}
class ContactImpl implements Contact{
    private String firstName;
    private String lastName;
    private String title;
    private String organization;
    
    public ContactImpl(){}
    public ContactImpl(String newFirstName, String newLastName,
        String newTitle, String newOrganization){
            firstName = newFirstName;
            lastName = newLastName;
            title = newTitle;
            organization = newOrganization;
    }
    
    public String getFirstName(){ return firstName; }
    public String getLastName(){ return lastName; }
    public String getTitle(){ return title; }
    public String getOrganization(){ return organization; }
    
    public void setFirstName(String newFirstName){ firstName = newFirstName; }
    public void setLastName(String newLastName){ lastName = newLastName; }
    public void setTitle(String newTitle){ title = newTitle; }
    public void setOrganization(String newOrganization){ organization = newOrganization; }
    
    public String toString(){
        return firstName + SPACE + lastName;
    }
}
class Deliverable implements ProjectItem{
    private String name;
    private String description;
    private Contact owner;
    
    public Deliverable(){ }
    public Deliverable(String newName, String newDescription,
        Contact newOwner){
        name = newName;
        description = newDescription;
        owner = newOwner;
    }
    
    public String getName(){ return name; }
    public String getDescription(){ return description; }
    public Contact getOwner(){ return owner; }
    public double getTimeRequired(){ return 0; }
    
    public void setName(String newName){ name = newName; }
    public void setDescription(String newDescription){ description = newDescription; }
    public void setOwner(Contact newOwner){ owner = newOwner; }
    
    public String toString(){
        return "Deliverable: " + name;
    }
}
class DependentProjectItem extends ProjectDecorator{
    private ProjectItem dependentItem;
    
    public DependentProjectItem(){ }
    public DependentProjectItem(ProjectItem newDependentItem){
        dependentItem = newDependentItem;
    }
    
    public ProjectItem getDependentItem(){ return dependentItem; }
    
    public void setDependentItem(ProjectItem newDependentItem){ dependentItem = newDependentItem; }
    
    public String toString(){
        return getProjectItem().toString() + EOL_STRING
            + "\tProjectItem dependent on: " + dependentItem;
    }
}
abstract class ProjectDecorator implements ProjectItem{
    private ProjectItem projectItem;
    
    protected ProjectItem getProjectItem(){ return projectItem; }
    public void setProjectItem(ProjectItem newProjectItem){ projectItem = newProjectItem; }
    
    public double getTimeRequired(){
        return projectItem.getTimeRequired();
    }
}
interface ProjectItem extends Serializable{
    public static final String EOL_STRING = System.getProperty("line.separator");
    public double getTimeRequired();
}
class Task implements ProjectItem{
    private String name;
    private ArrayList projectItems = new ArrayList();
    private Contact owner;
    private double timeRequired;
    
    public Task(){ }
    public Task(String newName, Contact newOwner,
        double newTimeRequired){
        name = newName;
        owner = newOwner;
        timeRequired = newTimeRequired;
    }
    
    public String getName(){ return name; }
    public ArrayList getProjectItems(){ return projectItems; }
    public Contact getOwner(){ return owner; }
    public double getTimeRequired(){
        double totalTime = timeRequired;
        Iterator items = projectItems.iterator();
        while(items.hasNext()){
            ProjectItem item = (ProjectItem)items.next();
            totalTime += item.getTimeRequired();
        }
        return totalTime;
    }
    
    public void setName(String newName){ name = newName; }
    public void setOwner(Contact newOwner){ owner = newOwner; }
    public void setTimeRequired(double newTimeRequired){ timeRequired = newTimeRequired; }
    
    public void addProjectItem(ProjectItem element){
        if (!projectItems.contains(element)){
            projectItems.add(element);
        }
    }
    public void removeProjectItem(ProjectItem element){
        projectItems.remove(element);
    }
    
    public String toString(){
        return "Task: " + name;
    }
}
class SupportedProjectItem extends ProjectDecorator{
    private ArrayList supportingDocuments = new ArrayList();
    
    public SupportedProjectItem(){ }
    public SupportedProjectItem(File newSupportingDocument){
        addSupportingDocument(newSupportingDocument);
    }
    
    public ArrayList getSupportingDocuments(){
        return supportingDocuments;
    }
    
    public void addSupportingDocument(File document){
        if (!supportingDocuments.contains(document)){
            supportingDocuments.add(document);
        }
    }
    
    public void removeSupportingDocument(File document){
        supportingDocuments.remove(document);
    }
    
    public String toString(){
        return getProjectItem().toString() + EOL_STRING
            + "\tSupporting Documents: " + supportingDocuments;
    }
}





Decorator pattern in Java

/*
The Design Patterns Java Companion
Copyright (C) 1998, by James W. Cooper
IBM Thomas J. Watson Research Center
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DecoWindow extends JFrame implements ActionListener {
  JButton Quit;
  public DecoWindow() {
    super("Deco Button");
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    JPanel jp = new JPanel();
    getContentPane().add(jp);
    jp.add(new CoolDecorator(new JButton("Cbutton")));
    jp.add(new SlashDecorator(new CoolDecorator(new JButton("Dbutton"))));
    //jp.add( new CoolDecorator(new JButton("Dbutton")));
    jp.add(Quit = new JButton("Quit"));
    Quit.addActionListener(this);
    setSize(new Dimension(200, 100));
    setVisible(true);
    Quit.requestFocus();
  }
  public void actionPerformed(ActionEvent e) {
    System.exit(0);
  }
  static public void main(String argv[]) {
    new DecoWindow();
  }
}
class Decorator extends JComponent {
  public Decorator(JComponent c) {
    setLayout(new BorderLayout());
    add("Center", c);
  }
}
class SlashDecorator extends Decorator {
  int x1, y1, w1, h1;
  public SlashDecorator(JComponent c) {
    super(c);
  }
  public void setBounds(int x, int y, int w, int h) {
    x1 = x;
    y1 = y;
    w1 = w;
    h1 = h;
    super.setBounds(x, y, w, h);
  }
  public void paint(Graphics g) {
    super.paint(g);
    g.setColor(Color.red);
    g.drawLine(0, 0, w1, h1);
  }
}
class CoolDecorator extends Decorator {
  boolean mouse_over; //true when mose over button
  JComponent thisComp;
  public CoolDecorator(JComponent c) {
    super(c);
    mouse_over = false;
    thisComp = this; //save this component
    //catch mouse movements in inner class
    c.addMouseListener(new MouseAdapter() {
      public void mouseEntered(MouseEvent e) {
        mouse_over = true; //set flag when mouse over
        thisComp.repaint();
      }
      public void mouseExited(MouseEvent e) {
        mouse_over = false; //clear flag when mouse not over
        thisComp.repaint();
      }
    });
  }
  //paint the button
  public void paint(Graphics g) {
    super.paint(g); //first draw the parent button
    if (!mouse_over)
    //if the mouse is not over the button
    //erase the borders
    {
      Dimension size = super.getSize();
      g.setColor(Color.lightGray);
      g.drawRect(0, 0, size.width - 1, size.height - 1);
      g.drawLine(size.width - 2, 0, size.width - 2, size.height - 1);
      g.drawLine(0, size.height - 2, size.width - 2, size.height - 2);
    }
  }
}