Java/Design Pattern/Decorator Pattern
Decorator Design Pattern in Java
<source lang="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>" + "" + DataLine + "" + "</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(); } }
}
</source>
Decorator Pattern 1
<source lang="java">
//[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; }
}
</source>
Decorator 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.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); } }
}
</source>