Reputation: 18796
This is a question on the behavior of the code rather then the pattern itself. I will lay out the code below
public abstract class Beverage {
protected String description;
public String getDescription(){
return description;
}
public abstract BigDecimal cost();
}
public abstract class CondimentDecorator extends Beverage{
@Override
public abstract String getDescription();
}
public class HouseBlend extends Beverage{
public HouseBlend() {
description = "House Blend";
}
@Override
public BigDecimal cost() {
return BigDecimal.valueOf(.89);
}
}
public class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
System.out.println("desc: " + beverage.getDescription());
return beverage.getDescription() + ", Mocha";
}
@Override
public BigDecimal cost() {
System.out.println("bev: "+beverage.cost());
return BigDecimal.valueOf(.20).add(beverage.cost());
}
}
public class CoffeeTest {
public static void main(String args[]){
Beverage blend = new HouseBlend();
blend = new Mocha(blend);
blend = new Mocha(blend);
blend = new Mocha(blend);
System.out.println(blend.getDescription() + " * "+blend.cost());
}
}
When CoffeeTest is run I get the following output which I would like to understand
1 desc: House Blend
2 desc: House Blend, Mocha
3 desc: House Blend
4 desc: House Blend, Mocha, Mocha
5 desc: House Blend
6 desc: House Blend, Mocha
7 desc: House Blend
8 bev: 0.89
9 bev: 1.09
10 bev: 0.89
11 bev: 1.29
12 bev: 0.89
13 bev: 1.09
14 bev: 0.89
15 House Blend, Mocha, Mocha, Mocha * 1.49
So these are my questions:
beverage.cost()
saving state by adding the amounts.I am sure the answers lie in polymorphism between Beverage and CondimentDecorator.
Upvotes: 3
Views: 489
Reputation: 6797
in Mocha.getDescription you have System.out.println and addiotionally you return something, that you print also in the void main. but nevertheless I get the following:
desc: House Blend
desc: House Blend, Mocha
desc: House Blend
bev: 0.89
bev: 1.09
bev: 0.89
House Blend, Mocha, Mocha * 1.29
if in void main you have three times new Mocha the output looks like yours
public static void main(String[] args) {
Beverage blend = new HouseBlend();
blend = new Mocha(blend);
blend = new Mocha(blend);
blend = new Mocha(blend);
System.out.println(blend.getDescription() + " * "+blend.cost());
}
decorator pattern works like wrapping objects around objects here it is like:
HouseBlend has_a ( Mocha has_a ( Mocha has_a ( Mocha ) ) )
Upvotes: 0
Reputation: 103135
How is 'House Blend, Mocha, Mocha' printed when there is no explicit state saved?
You are creating 3 distinct objects. Let us call them a, b and c. So we can rewrite the code to look like this:
Beverage a = new HouseBlend();
Beverage b = new Mocha(a);
Beverage c = new Mocha(b);
System.out.println(c.getDescription() + " * "+c.cost());
which will do the same thing as your code but it is clearer that you are dealing with 3 different objects. Assigning
blend = new Mocha(blend);
does not replace the object but actually creates a new object and simply modifies the reference blend to the new object.
When you call blend.getDescription() in your code you are referring to object c, which calls getDescription of object b which calls getDescription of object a. The getDescription() of object a returns the String "House Blend". So, getDescription() of object b returns "House Blend, Mocha". And getDescription() of object c then returns "House Blend, Mocha, Mocha".
A very similar thing happens to getCost().
Upvotes: 4
Reputation: 75599
In getDescription, you call beverage.getDescription() twice, both of which print lines.
Upvotes: 0