dimanche 10 juillet 2016

Proper way to use Composite Pattern

I'm learning about composite design pattern and I can't understand how can I treat every component the same (Leaf and Composite) when whenever I try to add or remove component from the Leaf I should get an error(or nothing should happen). This seems to be horrible design to me beacuse it violates the rule of inheritance to treat objects the same. The only way would be to somehow differentiate Composite from Leaf and always be aware with what am I working with. But this takes me back to original problem...

Component:

public abstract class Equipment {
    private String name;

    protected Equipment(String name){
        this.name = name;
    }

    public String name(){
        return name;
    }


    public abstract int power();
    public abstract double netPrice();
    public abstract double discountPrice();

    public abstract void add(Equipment equipment);
    public abstract void remove(Equipment equipment);

    public Iterable<Equipment> createIterator(){
        return Collections.emptyList();
    }
}

Composite:

public abstract class CompositeEquipment extends Equipment{
    private final List<Equipment> elements;

    protected CompositeEquipment(String name) {
        super(name);
        elements = new LinkedList<>();
    }

    @Override
    public double netPrice() {
        Iterable<Equipment> iter = createIterator();
        double total = 0;

        for (Iterator<Equipment> i = iter.iterator(); i.hasNext() ;) {
            Equipment next = i.next();
            total += next.netPrice();
        }

        return total;
    }

    @Override
    public Iterable<Equipment> createIterator() {
        return elements;
    }

    @Override
    public void remove(Equipment equipment){
        elements.remove(equipment);
    }

    @Override
    public void add(Equipment equipment){
        elements.add(equipment);
    }

}

Leaf:

public class FloppyDisk extends Equipment{

    public FloppyDisk(String name) {
        super(name);
    }

    @Override
    public int power() {
        return 1;
    }

    @Override
    public double netPrice() {
        return 3;
    }

    @Override
    public double discountPrice() {
        return 2.2;
    }

    @Override
    public void add(Equipment equipment) {
        //we well do nothing here because thats the final element of the tree
    }

    @Override
    public void remove(Equipment equipment) {
        //we well do nothing here because thats the final element of the tree
    }

}

The problem I see:

public void extendTheTree(Equipment equipment){
    equipment.add( new CompositeWithLeafs() );  //lets hope it is a Composite not a Leaf!!!
}

So how should I be using this pattern then or what scenarios??? The only solution I see is to get rid of the Leaf concept and use only Composits.

Aucun commentaire:

Enregistrer un commentaire