aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes Decorator Pattern Not Clear Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Decorator Pattern Not Clear" Watch "Decorator Pattern Not Clear" New topic
Author

Decorator Pattern Not Clear

Glenny Dsilva
Ranch Hand

Joined: May 09, 2005
Posts: 42
I am reading Head First Book on Design patterns

Found the decorator pattern a bit confusing . The code for decorator pattern in the book is below

Beverage code

public abstract class Beverage
{
String description = "Unknown Beverage";

public String getDescription()
{
return description;
}

public abstract double cost();
}


Condiments code

public abstract class CondimentDecorator extends Beverage
{
public abstract String getDescription();
}


public class HouseBlend extends Beverage
{
public HouseBlend()
{
description = "House Blend Coffee";
}
public double cost()
{
return .89;
}

}

// and finally ...

public class Mocha extends CondimentsDecorator
{
Beverage beverage;

public Mocha(Beverage beverage)
{
this.beverage = beverage;
}

public String getDescription()
{
return beverage.getDescription() + ", Mocha";
}

public double cost()
{
return .20 + beverage.cost()
}
}

public static void main(String args[])
{
Beverage beverage = new HouseBlend(); // here we get HouseBlend not U nknown beverage.



}


}

1. I would like to know why the getDescription() method in Condiment Decorator is marked abstract.

2. and does the instance variable gets overridden when i instantiate beverage class. (I was under the impression that instance variable are not overridden then what happens here).



Pls anyone clear my doubt..
Ryan McGuire
Ranch Hand

Joined: Feb 18, 2005
Posts: 988
    
    1
Originally posted by Glenny Dsilva:
I am reading Head First Book on Design patterns
1. I would like to know why the getDescription() method in Condiment Decorator is marked abstract.

2. and does the instance variable gets overridden when i instantiate beverage class. (I was under the impression that instance variable are not overridden then what happens here).



1. A couple things work together to make that the right thing to do:
  • The default implementation in Beverage, the superclass of CondimentDecorator, doesn't provide the right functionality for a CondimentDecorator.
  • It forces any concrete subclass, such as Mocha, to provide a more specific implementation.

  • By making CondimentDecorator.getDescription() abstract, Beverage.getDescription() becomes "hidden".

    2. Overridden? No, not in the sense of methods being overridden in subclasses. Each object of any of these classes will have a String instance variable named "description". The point is each object, even multiple instances of HouseBlend for instance, gets its own String. Now if description was turned into a class field with the static keyword, then the story would be different.

    However, when you make a new HouseBlend object the description field is assigned a value of "Unknown Beverage", which is then immediately overwritten with "House Blend Coffee" in the HouseBlend constructor. I guess in that sense, the old value of description is "overridden" with the new value, but that's not the usual OO definition of override.
    [ August 10, 2005: Message edited by: Ryan McGuire ]
    Mr. C Lamont Gilbert
    Ranch Hand

    Joined: Oct 05, 2001
    Posts: 1170

    are you sure tha tis supposed to be an example of the decorator pattern?
    Ryan McGuire
    Ranch Hand

    Joined: Feb 18, 2005
    Posts: 988
        
        1
    Originally posted by CL Gilbert:
    are you sure tha tis supposed to be an example of the decorator pattern?


    Looks like a perfectly good (albeit small) example to me. What has you concerened?
    Glenny Dsilva
    Ranch Hand

    Joined: May 09, 2005
    Posts: 42
    Still unclear Pls. explain these points.

    1. Even after removing the abstract method getDescription() in CondimentDecorator Class I get the same output so
    whats the point in having that method i.e. getDescription() in CondimentDecorator;

    2. The output for
    System.out.println(beverage2.getDescription() + beverage2.cost());

    is Dark Roast,mocha,mocha 2.39
    Pls. explain how mocha string is appended twice.


    The complete code is below



    // The Beverage class

    package test;

    public abstract class Beverage
    {
    String description = "Unknown Beverage";

    public String getDescription()
    {
    return description;
    }

    public abstract double cost();
    }

    // The CondimentDecorator Class

    package test;

    public abstract class CondimentDecorator extends Beverage
    {
    public abstract String getDescription(); // why this method

    }

    // The Dark Roast Class

    package test;

    public class DarkRoast extends Beverage
    {

    public DarkRoast()
    {
    description = "Dark Roast";
    }

    public double cost()
    {
    return 1.99;
    }

    }

    // The Mocha Class

    package test;

    public class Mocha extends CondimentDecorator
    {
    Beverage beverage;

    Mocha(Beverage beverage)
    {
    this.beverage = beverage;
    }

    public String getDescription()
    {
    return beverage.getDescription() + ",mocha";
    }

    public double cost()
    {
    return .20 + beverage.cost();
    }
    }

    // The main Class

    package test;

    public class StarBuzzCoffee
    {
    public static void main(String args[])
    {
    Beverage beverage2 = new DarkRoast();

    System.out.println(beverage2.getDescription() + "$" + beverage2.cost());


    beverage2 = new Mocha(beverage2);

    beverage2 = new Mocha(beverage2);

    System.out.println(beverage2.getDescription() + beverage2.cost());

    }
    }
    Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    Originally posted by Glenny Dsilva:
    1. Even after removing the abstract method getDescription() in CondimentDecorator Class I get the same output so
    whats the point in having that method i.e. getDescription() in CondimentDecorator;


    The purpose of the abstract method is to produce compile time error should you forget to override the getDescription method in a concrete decorator.


    2. The output for
    System.out.println(beverage2.getDescription() + beverage2.cost());

    is Dark Roast,mocha,mocha 2.39
    Pls. explain how mocha string is appended twice.


    Well, you have decorated the beverage with mocha twice, so it gets printed twice. What did you expect?


    The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
    Nikhil Vasaikar
    Ranch Hand

    Joined: Aug 18, 2004
    Posts: 56
    This example might help you understand the Decorator pattern better.
    Ryan McGuire
    Ranch Hand

    Joined: Feb 18, 2005
    Posts: 988
        
        1
    Originally posted by Ilja Preuss:

    The purpose of the abstract method is to produce compile time error should you forget to override the getDescription method in a concrete decorator.


    ...and to make sure you don't instantiate a CondimentDecorator object.
    Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    Originally posted by Ryan McGuire:


    ...and to make sure you don't instantiate a CondimentDecorator object.


    Well, for that it would suffice to make the *class* abstract, wouldn't it?
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Decorator Pattern Not Clear
     
    Similar Threads
    Doubt in Design Pattern "Decorator"
    HF Design Pattern Book - Question on Starbuzz
    Building a Decorator Question
    Doubt about Design Pattern
    Decorator Pattern.