# Composite pattern



## noisebreath (17. Mrz 2010)

Hi ich hab zum ersten mal ein composite pattern implementiert und mich da an einer kleinen vorgabe orientiert. 
ich wüsste gerne eure meinung zum CompositeEmployee interface von mir. Ist das so richtig? So hätte ich ja zB noch nicht den Konstruktor der Employee klasse verlangt. 
Was gibt es bei meiner Lösung noch zu kritisieren ist eigentlich meine Frage 

Interface:

```
public interface CompositeEmployee {

	public float getSalary();
	public String getName();
	public void add(Employee e);
	public void remove(Employee e);
	public Enumeration elements();
	public float getSalaries();
	public Employee getChild(String selectedChild);
	
}
```
Objekt: 

```
public class Employee implements CompositeEmployee{
	String name;
	float salary;
	Vector subordinates;
	//--------------------------------------
	public Employee(String _name, float _salary) {
		name = _name;
		salary = _salary;
		subordinates = new Vector();
	}
	public float getSalary() {
		return salary;
	}
	public String getName() {
		return name;
	}
	public void add(Employee e) {
		subordinates.addElement(e);
	}
	public void remove(Employee e) {
		subordinates.removeElement(e);
	}
	public Enumeration elements() {
		return subordinates.elements();
	}
	public float getSalaries() {
		float sum = salary; //this one’s salary
		//add in subordinates salaries
		for(int i = 0; i < subordinates.size(); i++) {
			sum +=((Employee)subordinates.elementAt(i)).getSalaries();
		}
		return sum;
	}
	public Employee getChild(String selectedChild) {
	     for (Enumeration e = subordinates.elements() ; e.hasMoreElements() ;) {
	    	 Employee emp = (Employee)e.nextElement();
	         if(emp.getName().equals(selectedChild)){
	        	 return emp;
	         }else{
	        	 Employee rekursicEmp = emp.getChild(selectedChild);
	        	 if(rekursicEmp!=null)
	        		 return rekursicEmp;
	         }
	     }
	     return null;
	}
}
```
Main:

```
public class Main {
	private static Employee marketVP;
	private static Employee prodVP;
	private static Employee salesMgr;
	private static Employee advMgr;
	private static Employee boss;
	private static Employee prodMgr;
	private static Employee shipMgr;
	public static void main(String[] args) {
		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));
		//add salesmen reporting to Sales Manager
		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));
		//add manufacturing staff
		for (int i = 0; i < 4; i++)
			prodMgr.add( new Employee("Manuf "+	new Integer(i).toString(), 25000.0F	+(float)(Math.random()-0.5)*5000));
		//add shipping clerks
		for (int i = 0; i < 3; i++)
		shipMgr.add( new Employee("ShipClrk " + new Integer(i).toString(), 20000.0F +(float)(Math.random()-0.5)*5000));
		JFrame frame = new JFrame();
		frame.setBounds(400,400,400,400);
		DefaultMutableTreeNode top = new DefaultMutableTreeNode();
		JTree tree = new JTree(top);
		tree.addTreeSelectionListener(new TreeListener());
		addNodes(top,boss);
		frame.add(tree);
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
	private static 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);
			}
	}
	public static class TreeListener implements TreeSelectionListener {
		@Override
		public void valueChanged(TreeSelectionEvent arg0) {
			//called when employee is selected in tree list
			TreePath path = arg0.getPath();
			String selectedChild = path.getLastPathComponent().toString();
			//find that employee in the composite
			Employee emp = boss.getChild(selectedChild);
			//display sum of salaries of subordinates(if any)
			if(emp != null)
				System.out.println(new Float(emp.getSalaries()).toString());
		}
	}
}
```

Vielen Dank für die Diskussion im voraus! 

lg
noise


----------



## ice-breaker (17. Mrz 2010)

Ich habe ehrlich gesagt noch nie gesehen, dass eine Klasse Kompositum und "primitives" Objekt zugleich ist, ich vermute mal auch, dass es nicht gewünscht ist, denn dein Objekt Employee hält sich nicht an die SingleResponsibility-Regel. Es ist Mitarbeiter und ggf. eine Abteilung von Mitarbeitern zugleich.

Schau dir mal auf Wikipedia den Artikel zum Composite-Pattern an, in deinem Modell müsste das Blatt der Employee sein und das Kompositum eine Abteilung sein.
Dadurch müsste im Interface auch die 
	
	
	
	





```
getSalaries()
```
-Methode verschwinden


----------



## MQue (23. Mrz 2010)

So sehe ich das genauso, das eine Klasse gleichzeitig ein Blatt und ein Baum ist, hab ich auch noch nie gesehen, deshalb tust du dir auch sehr schwer, einen richtigen Namen für die Klasse zu finden, 
Also ich würd die Klassenaufteilung auch so machen wie es im Wikipedia angeführt ist, 
da kannst du dann nicht falsch machen.
Beste Grüße,
MQue


----------

