Java/Design Pattern/Composite Pattern
Composite Pattern 2
<source lang="java">
//[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); }
}
</source>
Composite 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.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; }
}
</source>
Composite Patterns in Java 2
<source lang="java">
/* 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
</source>