Java/Design Pattern/Composite Pattern
Composite Pattern 2
//[C] 2002 Sun Microsystems, Inc.---
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
public class RunCompositePattern {
public static void main(String [] arguments){
System.out.println("Example for the Composite pattern");
System.out.println();
System.out.println("This code sample will propagate a method call throughout");
System.out.println(" a tree structure. The tree represents a project, and is");
System.out.println(" composed of three kinds of ProjectItems - Project, Task,");
System.out.println(" and Deliverable. Of these three classes, Project and Task");
System.out.println(" can store an ArrayList of ProjectItems. This means that");
System.out.println(" they can act as branch nodes for our tree. The Deliverable");
System.out.println(" is a terminal node, since it cannot hold any ProjectItems.");
System.out.println();
System.out.println("In this example, the method defined by ProjectItem,");
System.out.println(" getTimeRequired, provides the method to demonstrate the");
System.out.println(" pattern. For branch nodes, the method will be passed on");
System.out.println(" to the children. For terminal nodes (Deliverables), a");
System.out.println(" single value will be returned.");
System.out.println();
System.out.println("Note that it is possible to make this method call ANYWHERE");
System.out.println(" in the tree, since all classes implement the getTimeRequired");
System.out.println(" method. This means that you are able to calculate the time");
System.out.println(" required to complete the whole project OR any part of it.");
System.out.println();
System.out.println("Deserializing a test Project for the Composite pattern");
System.out.println();
if (!(new File("data.ser").exists())){
DataCreator.serialize("data.ser");
}
Project project = (Project)(DataRetriever.deserializeData("data.ser"));
System.out.println("Calculating total time estimate for the project");
System.out.println("\t" + project.getDescription());
System.out.println("Time Required: " + project.getTimeRequired());
}
}
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 DataCreator{
private static final String DEFAULT_FILE = "data.ser";
public static void main(String [] args){
String fileName;
if (args.length == 1){
fileName = args[0];
}
else{
fileName = DEFAULT_FILE;
}
serialize(fileName);
}
public static void serialize(String fileName){
try{
serializeToFile(createData(), fileName);
}
catch (IOException exc){
exc.printStackTrace();
}
}
private static Serializable createData(){
Contact contact1 = new ContactImpl("Dennis", "Moore", "Managing Director", "Highway Man, LTD");
Contact contact2 = new ContactImpl("Joseph", "Mongolfier", "High Flyer", "Lighter than Air Productions");
Contact contact3 = new ContactImpl("Erik", "Njoll", "Nomad without Portfolio", "Nordic Trek, Inc.");
Contact contact4 = new ContactImpl("Lemming", "", "Principal Investigator", "BDA");
Project project = new Project("IslandParadise", "Acquire a personal island paradise");
Deliverable deliverable1 = new Deliverable("Island Paradise", "", contact1);
Task task1 = new Task("Fortune", "Acquire a small fortune", contact4, 11.0);
Task task2 = new Task("Isle", "Locate an island for sale", contact2, 7.5);
Task task3 = new Task("Name", "Decide on a name for the island", contact3, 3.2);
project.addProjectItem(deliverable1);
project.addProjectItem(task1);
project.addProjectItem(task2);
project.addProjectItem(task3);
Deliverable deliverable11 = new Deliverable("$1,000,000", "(total net worth after taxes)", contact1);
Task task11 = new Task("Fortune1", "Use psychic hotline to predict winning lottery numbers", contact4, 2.5);
Task task12 = new Task("Fortune2", "Invest winnings to ensure 50% annual interest", contact1, 14.0);
task1.addProjectItem(task11);
task1.addProjectItem(task12);
task1.addProjectItem(deliverable11);
Task task21 = new Task("Isle1", "Research whether climate is better in the Atlantic or Pacific", contact1, 1.8);
Task task22 = new Task("Isle2", "Locate an island for auction on EBay", contact4, 5.0);
Task task23 = new Task("Isle2a", "Negotiate for sale of the island", contact3, 17.5);
task2.addProjectItem(task21);
task2.addProjectItem(task22);
task2.addProjectItem(task23);
Deliverable deliverable31 = new Deliverable("Island Name", "", contact1);
task3.addProjectItem(deliverable31);
return project;
}
private static void serializeToFile(Serializable content, String fileName) throws IOException{
ObjectOutputStream serOut = new ObjectOutputStream(new FileOutputStream(fileName));
serOut.writeObject(content);
serOut.close();
}
}
class DataRetriever{
public static Object deserializeData(String fileName){
Object returnValue = null;
try{
File inputFile = new File(fileName);
if (inputFile.exists() && inputFile.isFile()){
ObjectInputStream readIn = new ObjectInputStream(new FileInputStream(fileName));
returnValue = readIn.readObject();
readIn.close();
}else{
System.err.println("Unable to locate the file " + fileName);
}
}catch (ClassNotFoundException exc){
exc.printStackTrace();
}catch (IOException exc){
exc.printStackTrace();
}
return returnValue;
}
}
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; }
}
class Project implements ProjectItem{
private String name;
private String description;
private ArrayList projectItems = new ArrayList();
public Project(){ }
public Project(String newName, String newDescription){
name = newName;
description = newDescription;
}
public String getName(){ return name; }
public String getDescription(){ return description; }
public ArrayList getProjectItems(){ return projectItems; }
public double getTimeRequired(){
double totalTime = 0;
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 setDescription(String newDescription){ description = newDescription; }
public void addProjectItem(ProjectItem element){
if (!projectItems.contains(element)){
projectItems.add(element);
}
}
public void removeProjectItem(ProjectItem element){
projectItems.remove(element);
}
}
interface ProjectItem extends Serializable{
public double getTimeRequired();
}
class Task implements ProjectItem{
private String name;
private String details;
private ArrayList projectItems = new ArrayList();
private Contact owner;
private double timeRequired;
public Task(){ }
public Task(String newName, String newDetails,
Contact newOwner, double newTimeRequired){
name = newName;
details = newDetails;
owner = newOwner;
timeRequired = newTimeRequired;
}
public String getName(){ return name; }
public String getDetails(){ return details; }
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 setDetails(String newDetails){ details = newDetails; }
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);
}
}
Composite 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.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.border.BevelBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
public class EmpTree extends JFrame implements TreeSelectionListener {
Employee boss, marketVP, prodVP;
Employee salesMgr, advMgr;
Employee prodMgr, shipMgr;
JScrollPane sp;
JPanel treePanel;
JTree tree;
DefaultMutableTreeNode troot;
JLabel cost;
public EmpTree() {
super("Employee tree");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
makeEmployees();
setGUI();
}
//--------------------------------------
private void setGUI() {
treePanel = new JPanel();
getContentPane().add(treePanel);
treePanel.setLayout(new BorderLayout());
sp = new JScrollPane();
treePanel.add("Center", sp);
treePanel.add("South", cost = new JLabel(" "));
treePanel.setBorder(new BevelBorder(BevelBorder.RAISED));
troot = new DefaultMutableTreeNode(boss.getName());
tree = new JTree(troot);
tree.setBackground(Color.lightGray);
loadTree(boss);
/* Put the Tree in a scroller. */
sp.getViewport().add(tree);
setSize(new Dimension(200, 300));
setVisible(true);
}
//------------------------------------
public void loadTree(Employee topDog) {
DefaultMutableTreeNode troot;
troot = new DefaultMutableTreeNode(topDog.getName());
treePanel.remove(tree);
tree = new JTree(troot);
tree.addTreeSelectionListener(this);
sp.getViewport().add(tree);
addNodes(troot, topDog);
tree.expandRow(0);
repaint();
}
//--------------------------------------
private void addNodes(DefaultMutableTreeNode pnode, Employee emp) {
DefaultMutableTreeNode node;
Enumeration e = emp.elements();
while (e.hasMoreElements()) {
Employee newEmp = (Employee) e.nextElement();
node = new DefaultMutableTreeNode(newEmp.getName());
pnode.add(node);
addNodes(node, newEmp);
}
}
//--------------------------------------
private void makeEmployees() {
boss = new Employee("CEO", 200000);
boss.add(marketVP = new Employee("Marketing VP", 100000));
boss.add(prodVP = new Employee("Production VP", 100000));
marketVP.add(salesMgr = new Employee("Sales Mgr", 50000));
marketVP.add(advMgr = new Employee("Advt Mgr", 50000));
for (int i = 0; i < 5; i++)
salesMgr.add(new Employee("Sales " + new Integer(i).toString(),
30000.0F + (float) (Math.random() - 0.5) * 10000));
advMgr.add(new Employee("Secy", 20000));
prodVP.add(prodMgr = new Employee("Prod Mgr", 40000));
prodVP.add(shipMgr = new Employee("Ship Mgr", 35000));
for (int i = 0; i < 4; i++)
prodMgr.add(new Employee("Manuf " + new Integer(i).toString(),
25000.0F + (float) (Math.random() - 0.5) * 5000));
for (int i = 0; i < 3; i++)
shipMgr.add(new Employee("ShipClrk " + new Integer(i).toString(),
20000.0F + (float) (Math.random() - 0.5) * 5000));
}
//--------------------------------------
public void valueChanged(TreeSelectionEvent evt) {
TreePath path = evt.getPath();
String selectedTerm = path.getLastPathComponent().toString();
Employee emp = boss.getChild(selectedTerm);
if (emp != null)
cost.setText(new Float(emp.getSalaries()).toString());
}
//--------------------------------------
static public void main(String argv[]) {
new EmpTree();
}
}
class Employee {
String name;
float salary;
Vector subordinates;
boolean isLeaf;
Employee parent = null;
//--------------------------------------
public Employee(String _name, float _salary) {
name = _name;
salary = _salary;
subordinates = new Vector();
isLeaf = false;
}
//--------------------------------------
public Employee(Employee _parent, String _name, float _salary) {
name = _name;
salary = _salary;
parent = _parent;
subordinates = new Vector();
isLeaf = false;
}
//--------------------------------------
public void setLeaf(boolean b) {
isLeaf = b; //if true, do not allow children
}
//--------------------------------------
public float getSalary() {
return salary;
}
//--------------------------------------
public String getName() {
return name;
}
//--------------------------------------
public boolean add(Employee e) {
if (!isLeaf)
subordinates.addElement(e);
return isLeaf; //false if unsuccessful
}
//--------------------------------------
public void remove(Employee e) {
if (!isLeaf)
subordinates.removeElement(e);
}
//--------------------------------------
public Enumeration elements() {
return subordinates.elements();
}
//--------------------------------------
public Employee getChild(String s) {
Employee newEmp = null;
if (getName().equals(s))
return this;
else {
boolean found = false;
Enumeration e = elements();
while (e.hasMoreElements() && (!found)) {
newEmp = (Employee) e.nextElement();
found = newEmp.getName().equals(s);
if (!found) {
newEmp = newEmp.getChild(s);
found = (newEmp != null);
}
}
if (found)
return newEmp;
else
return null;
}
}
//--------------------------------------
public float getSalaries() {
float sum = salary;
for (int i = 0; i < subordinates.size(); i++) {
sum += ((Employee) subordinates.elementAt(i)).getSalaries();
}
return sum;
}
}
Composite Patterns in Java 2
/*
Software Architecture Design Patterns in Java
by Partha Kuchana
Auerbach Publications
*/
import java.util.Enumeration;
import java.util.Vector;
public class CompositeDemo {
public static final String SEPARATOR = ", ";
public static void main(String[] args) {
FileSystemComponent mainFolder = new DirComponent("Year2000");
FileSystemComponent subFolder1 = new DirComponent("Jan");
FileSystemComponent subFolder2 = new DirComponent("Feb");
FileSystemComponent folder1File1 = new FileComponent(
"Jan1DataFile.txt", 1000);
FileSystemComponent folder1File2 = new FileComponent(
"Jan2DataFile.txt", 2000);
FileSystemComponent folder2File1 = new FileComponent(
"Feb1DataFile.txt", 3000);
FileSystemComponent folder2File2 = new FileComponent(
"Feb2DataFile.txt", 4000);
try {
mainFolder.addComponent(subFolder1);
mainFolder.addComponent(subFolder2);
subFolder1.addComponent(folder1File1);
subFolder1.addComponent(folder1File2);
subFolder2.addComponent(folder2File1);
subFolder2.addComponent(folder2File2);
} catch (CompositeException ex) {
//
}
//Client refers to both composite &
//individual components in a uniform manner
System.out.println(" Main Folder Size= "
+ mainFolder.getComponentSize() + "kb");
System.out.println(" Sub Folder1 Size= "
+ subFolder1.getComponentSize() + "kb");
System.out.println(" File1 in Folder1 size= "
+ folder1File1.getComponentSize() + "kb");
}
}
class FileComponent extends FileSystemComponent {
private long size;
public FileComponent(String cName, long sz) {
super(cName);
size = sz;
}
public long getComponentSize() {
return size;
}
} // End of class
abstract class FileSystemComponent {
String name;
public FileSystemComponent(String cName) {
name = cName;
}
public void addComponent(FileSystemComponent component)
throws CompositeException {
throw new CompositeException("Invalid Operation. Not Supported");
}
public FileSystemComponent getComponent(int componentNum)
throws CompositeException {
throw new CompositeException("Invalid Operation. Not Supported");
}
public abstract long getComponentSize();
} // End of class FileSystemComponent
class CompositeException extends Exception {
public CompositeException(String msg) {
super(msg);
}
} // End of class
class DirComponent extends FileSystemComponent {
Vector dirContents = new Vector();
//individual files/sub folders collection
public DirComponent(String cName) {
super(cName);
}
public void addComponent(FileSystemComponent fc) throws CompositeException {
dirContents.add(fc);
}
public FileSystemComponent getComponent(int location)
throws CompositeException {
return (FileSystemComponent) dirContents.elementAt(location);
}
public long getComponentSize() {
long sizeOfAllFiles = 0;
Enumeration e = dirContents.elements();
while (e.hasMoreElements()) {
FileSystemComponent component = (FileSystemComponent) e
.nextElement();
sizeOfAllFiles = sizeOfAllFiles + (component.getComponentSize());
}
return sizeOfAllFiles;
}
} // End of class