Java/Design Pattern/Decorator Pattern
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);
}
}
}