Decorator Pattern question C# / java -
i looking @ this wikipedia article, , couldn't understand how hell working. little bit frustrated not being able understand code looking @ it, dedided port code c# (i'm .net, sorry guys :)). minor modifications needed (inherits , extends, base super, etc) , run app. surprise, got following output :
cost: 1 ingredient: coffee cost: 1 ingredient: coffee cost: 1 ingredient: coffee cost: 1 ingredient: coffee
just curious, can java dev tell me what's different here , why wikipedia example works (if work does, of course).
namespace consoleapplication1 { class program { static void main(string[] args) { coffee samplecoffee = new simplecoffee(); console.writeline("cost: " + samplecoffee.getcost() + " ingredient: " + samplecoffee.getingredient()); samplecoffee = new milk(samplecoffee); console.writeline("cost: " + samplecoffee.getcost() + " ingredient: " + samplecoffee.getingredient()); samplecoffee = new sprinkles(samplecoffee); console.writeline("cost: " + samplecoffee.getcost() + " ingredient: " + samplecoffee.getingredient()); samplecoffee = new whip(samplecoffee); console.writeline("cost: " + samplecoffee.getcost() + " ingredient: " + samplecoffee.getingredient()); console.readkey(); } } //the coffee interface defines functionality of coffee implemented decorator public interface coffee { double getcost(); // returns cost of coffee string getingredient(); //returns ingredients mixed coffee } //implementation of simple coffee without ingredients public class simplecoffee : coffee { double cost; string ingredient; public simplecoffee() { cost = 1; ingredient = "coffee"; } public double getcost() { return cost; } public string getingredient() { return ingredient; } } //abstract decorator class - note implements coffee interface abstract public class coffeedecorator : coffee { protected coffee decoratedcoffee; protected string ingredientseparator; public coffeedecorator(coffee decoratedcoffee) { this.decoratedcoffee = decoratedcoffee; ingredientseparator = ", "; } public coffeedecorator() { } public double getcost() //note implements getcost function defined in interface coffee { return decoratedcoffee.getcost(); } public string getingredient() { return decoratedcoffee.getingredient(); } } //decorator milk mixes milk coffee //note extends coffeedecorator public class milk : coffeedecorator { double cost; string ingredient; public milk(coffee decoratedcoffee) : base(decoratedcoffee) { cost = 0.5; ingredient = "milk"; } public double getcost() { return base.getcost() + cost; } public string getingredient() { return base.getingredient() + base.ingredientseparator + ingredient; } } //decorator whip mixes whip coffee //note extends coffeedecorator public class whip : coffeedecorator { double cost; string ingredient; public whip(coffee decoratedcoffee) : base(decoratedcoffee) { cost = 0.7; ingredient = "whip"; } public double getcost() { return base.getcost() + cost; } public string getingredient() { return base.getingredient() + base.ingredientseparator + ingredient; } } //decorator sprinkles mixes sprinkles coffee //note extends coffeedecorator public class sprinkles : coffeedecorator { double cost; string ingredient; public sprinkles(coffee decoratedcoffee) : base(decoratedcoffee) { cost = 0.2; ingredient = "sprinkles"; } public double getcost() { return base.getcost() + cost; } public string getingredient() { return base.getingredient() + base.ingredientseparator + ingredient; } } }
yes - methods virtual default in java, not in c#.
you should have received warnings when compiling code, talking "new" modifier. should have given clue. milk
(etc) methods hiding or shadowing in coffeedecorator
- they're not being called polymorphically.
you'd need make coffeedecorator
methods virtual virtual
modifier, , explicitly override them in milk
(etc) override
modifier.
// in coffeedecorator public virtual double getcost() { return decoratedcoffee.getcost(); } // in milk public override double getcost() { return base.getcost() + cost; }
Comments
Post a Comment