This week's book giveaways are in the Refactoring and Agile forums.
We're giving away four copies each of Re-engineering Legacy Software and Docker in Action and have the authors on-line!
See this thread and this one for details.
Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How to have single overall properties for an object created with the decorator pattern?

 
Scott Shipp
Ranch Hand
Posts: 191
10
Eclipse IDE IntelliJ IDE Java Scala Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone,

Have ran into a case similar to the following. Let's use a simple example for discussion purposes. Say you want to make a "Pepperoni Pizza" and you use the decorator pattern. So you end up with some statement like:



Pepperoni, Onions, Mozzarella, TomatoSauce, PlainPizza all extend a "PizzaDecorator" abstract class so this works to combine their shared properties like cost, toppings into one object.

But the issue I am having is when I want a single property or properties which applies only to this specific combination, like a name property (Name="Pepperoni Pizza.")

What is the recommended way to do this?
 
Ryan McGuire
Ranch Hand
Posts: 1055
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know that there is one single recommended way to do this, but I can think of a couple possibilities that depend on the details of what you're after.

1. If the outermost PizzaDecorator is what determines the name, then just have each PizzaDecorator return a hardcoded name. The Pepperoni decorator would return "Pepperoni Pizza".



That would print "name1 = Pepperoni Pizza; name2 = Onion Pizza" even though the two pizzas would have the same list of ingredients.

2. Work out a name precedence scheme so that "high-priority" ingredient names like "Pepperoni" override lower ones like "Cheese", but not vice-versa.
  • PlainPizza would return "Plain Pizza" with a precedence of 0.
  • TomatoSauce would return "Sauce Pizza" with a precedence of 1.
  • Mozzarella would return "Cheese Pizza" with a precedence of 2.
  • ColbyJack would return "CJCheese Pizza" also with a precedence of 2.
  • Onions would return "Onion Pizza" with a precedence of 3.
  • Pepperoni would return "Pepperoni Pizza" with a precedence of 4.
  • Sausage would return "Sausage Pizza" with a precedence of 4.
  • Ham would return "Ham Pizza" with a precedence of 4.




  • So...



    ...would print...

    name1 = Pepperoni Pizza; name2 = Pepperoni Pizza; name3 = Ham Pizza; name1 = Pepperoni Pizza

    It would be possible to develop more complicated schemes for combining each decorator's name with those of the client. e.g. Maybe if my name precedence is equal to my client's, then I'll prepend my ingredient with an "and":
    new Sausage(new Pepperoni(new Onion(new Ham(new Mozzarella(new TomatoSauce(new PlainPizza())))))).Name(); could return "Sausage and Pepperoni and Ham Pizza"

    You could either work this into the PizzaDecorator class or create a separate Strategy object that looks at the whole hierarchy of PizzaDecorators and determines the correct name. e.g. If (the list of decorators contains at least one Ham and at least one Pineapple and no other meats) then name = "Hawaiian Pizza".
     
    Jayesh A Lalwani
    Rancher
    Posts: 2756
    32
    Eclipse IDE Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If the name is a property of the Combination, not the ingredients that decorate the pizza, then I wouldn't make name as a property of the pizza. Decorator pattern applies to behavior that can be decorated (for example cost). If a behavior cannot be decorated (for example name), you shouldn't be using a decorator pattern. Trying to put non-decorator like behavior on a decorator pattern is like putting a square peg in a round hole.

    Actually, the pizza example is used to illustrate decorator pattern, but in real life, I wouldn't use a decorator pattern for pizzas, because real life pizza behavior doesn't follow decorator pattern. What if you want to model pizzas that have half the ingredients on one side, and other half on another side? What if you get a discount for using certain number of ingredients? No sirree bob.. I stick with composite pattern thankyouveddymuch

    IMO, the perfect example of decorator pattern is InputStream interface. Beautifully thought out and implemented.
     
    Scott Shipp
    Ranch Hand
    Posts: 191
    10
    Eclipse IDE IntelliJ IDE Java Scala Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Appreciate the replies, both of you! Lots to think about. Thanks!
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic