Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6179113
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T00:35:41+00:00 2026-05-24T00:35:41+00:00

Most of you know the pizza / cofee example for the decorator pattern. Pizza*

  • 0

Most of you know the pizza / cofee example for the decorator pattern.

Pizza* pizza1 = BigPizzaDecorator(MushromDecorator(SimplePizza()));
Pizza* pizza2 = MushromDecorator(BigPizzaDecorator(SimplePizza()));

the two object behave in a similar way, but not completely, in particular if you have non-commutative operation, for example:

BigPizzaDecorator::price() { return 10 + PizzaDecorator::price(); }  // this is commutative
BigPizzaDecorator::name() { return "big " + PizzaDecorator::name(); } // this is not commutative

So the price for pizza1 and pizza2 are the same, but the name is not, for example the first should be "Big mushroom pizza", the second "Mushroom big pizza". The first is english correct (probably better would be “Big pizza with mushroom”, but it’s not so important).

The book “Head first” point out this problem with the Cofee example:

When you need to peek at multiple layers into the decorator chain, you
are starting to push the decorator beyond its true intent.

Nevertheless, such things are possible. Imagine a CondimentPrettyPrint
decorator that parses the final decription and can print “Mocha, Whip,
Mocha” as “Whip, Double Mocha.”

what is the best way to do that? (operator< ?)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T00:35:42+00:00Added an answer on May 24, 2026 at 12:35 am

    Ive never known this sort of thing to be needed when using decorators. And I would think that if you need to do this, then you shouldn’t be using decorators, especially as you’re knowingly “pushing the decorator beyond it’s intent”.

    I have had a stab at doing this, the code is below. Basically, I create a thin layer around the SimplePizza object that understands what the decorators need, then the decorators decorate that.

    The main problem here, is that to maintain order in the output, you would have to maintain a relationship between decorators – which can quickly become a maintenance nightmare.

    #include <iostream>
    #include <queue>
    #include <sstream>
    
    struct name_part
    {
        std::string mName;
        int         mPriority;
    
        name_part(const std::string& name, int priority)
        : mName(name)
        , mPriority(priority)
        {
        }
    };
    
    bool operator<(const name_part& a, const name_part& b)
    {
        return (a.mPriority < b.mPriority);
    }
    
    std::string priority_queueToString(const std::priority_queue<name_part>& orig)
    {
        std::ostringstream oss;
        std::priority_queue<name_part> q(orig);
    
        while (!q.empty())
        {
            oss << q.top().mName << " ";
            q.pop();
        }
    
        return oss.str();
    }
    
    struct SimplePizza
    {
        virtual std::string name()
        {
            return "pizza";
        }
    };
    
    struct SimplePizzaImplementer : SimplePizza
    {
        SimplePizza *mDecorated;
    
        SimplePizzaImplementer()
        : mDecorated(0)
        {
        }
    
        SimplePizzaImplementer(SimplePizza *decorated)
        : mDecorated(decorated)
        {
        }
    
        virtual std::string name()
        {
            return priority_queueToString(nameParts());
        }
    
        virtual std::priority_queue<name_part> nameParts()
        {
            std::priority_queue<name_part> q;
    
            if (mDecorated)
            {
                q.push(name_part(mDecorated->name(), 0));
            }
    
            return q;
        }
    };
    
    struct MushroomDecorator : SimplePizzaImplementer
    {
        SimplePizzaImplementer *mDecorated;
    
        MushroomDecorator(SimplePizzaImplementer *decorated)
        : mDecorated(decorated)
        {
        }
    
        virtual std::string name()
        {
            return priority_queueToString(nameParts());
        }
    
        virtual std::priority_queue<name_part> nameParts()
        {
            std::priority_queue<name_part> q = mDecorated->nameParts();
            q.push(name_part("mushroom", 1));
            return q;
        }
    };
    
    struct BigDecorator : SimplePizzaImplementer
    {
        SimplePizzaImplementer *mDecorated;
    
        BigDecorator(SimplePizzaImplementer *decorated)
        : mDecorated(decorated)
        {
        }
    
        virtual std::string name()
        {
            return priority_queueToString(nameParts());
        }
    
        virtual std::priority_queue<name_part> nameParts()
        {
            std::priority_queue<name_part> q = mDecorated->nameParts();
            q.push(name_part("big", 2));
            return q;
        }
    };
    
    int main()
    {
        SimplePizzaImplementer *impl = new SimplePizzaImplementer(new SimplePizza());
        SimplePizza *pizza1 = new MushroomDecorator(new BigDecorator(impl));
        SimplePizza *pizza2 = new BigDecorator(new MushroomDecorator(impl));
    
        std::cout << pizza1->name() << std::endl;
        std::cout << pizza2->name() << std::endl;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I will choose Java as an example, most people know it, though every other
As most should know close() also closes any streams uses. This allows the follow
I think most people know how to do this via the GUI (right click
As I think most people know already, or if you don't, FPDF released a
I know that most links should be left up to the end-user to decide
I know that most people recommend using HttpRuntime.Cache because it has more flexibility... etc.
I'm trying to implement a version control system, but as most of us know
I know I can do most of this by hacking Trac and using Git
As most of you would know, if I drop a file named app_offline.htm in
Does anybody know which JSF version is most suitable to use when deploying to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.