Decorator Design Patterns Question

Feb 13, 2015 at 10:14am
Hello everybody,

I'm trying to implement a decorator design pattern in the code below. With this I get :

Base model of Ferrari costs $31000.
Unknown Car will cost you $31300

But I actually expect this :

Base model of Ferrari costs $31000.
Ferrari with Navigation will cost you $31300

Can anyone help understand why it is what I get and not what i'm expecting?

Thank you!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using namespace std;

class Car
{
    protected : 
        string _str;
    public:
        Car(){
            _str=" Unknown Car ";
        };
        virtual ~Car(){
        //    cout << " #>~Car <# " << endl;
        };
        virtual double getCost()=0;
        virtual string getDescription() const{
            return _str;
        };
};


class OptionsDecorator : public Car
{
    public:
        virtual string getDescription()=0;
        virtual ~OptionsDecorator(){
        //   cout << " #>~OptionsDecorator<# " << endl;
        };
};

class Ferrari :  public Car
{
    public:
        Ferrari (){
            _str=" Ferrari ";
        //    cout << " #>Ferrari<#" << endl;
        };
        virtual double getCost(){
            return 31000.0;
        };
        ~Ferrari () {
        //    cout << " #>~Ferrari<#" << endl;
        };
};

class Navigation : public OptionsDecorator 
{
    private:
        Car* _b;
    public:
        Navigation (Car* b){
            _b=b;
        };
        virtual string getDescription(){
            stringstream ss;
            ss << _b->getDescription() << " with Navigation " ;
            return ss.str() ;
        };
        double getCost(){
            return _b->getCost()+300.0;
        };
        virtual ~Navigation ()
        {
        //    cout << " #>~Navigation<# " << endl;
        };
};

class CarDecorationExample{
    public:
        static void execute(){
            Car* b=new Ferrari ;
            cout << "Base model of " << b->getDescription() << " costs $" << b->getCost() << "." << endl;
            b=new Navigation (b);
            cout << b->getDescription() << " will cost you $" << b->getCost();
            delete b;
        };
};
int main()
{

     CarDecorationExample::execute();      
     return 0;   
}
Feb 13, 2015 at 10:26am
Why do you think it would output you that?

Class hierarchy for Navigator is Navigation → OptionsDecorator → Car. In no place there is a Ferrari there.
It is not a Decorator pattern, it is example of code Decorator should replace.

Look at these: http://www.vincehuston.org/dp/decorator.html
http://sourcemaking.com/design_patterns/decorator (Example in C++ at the end of page)
Feb 13, 2015 at 10:59am
Thank you for the quick response,

Navigation has Ferrari as member and a getDescription() method which is inherited from Car. So I think that Navigation overrides the getDescription() by putting Ferrari->getDescription() + "with Navigation".

OOP is new to me, can you help me understand why i don't get "Ferrari with Navigation will cost ... " ?

Really thanks for the links, i picked the example from Wikibooks and I have no idea if it is a good reference to learn design patterns

Regards
Feb 13, 2015 at 11:15am
Sorry, I did not noticed that navigation contains car pointer.
In your code this virtual string getDescription(){ is never called, as Car (type of pointer itself) does not have such member, so virtual string getDescription() const{ is called instead, and as your decorator class is derived from Car itself and do not change own _str member, it is outputted.
Feb 13, 2015 at 12:27pm
Oh yes! didn't pay attention to the const
Thank you!

any advice for learning design patterns? what do you think of the wikibook link here presenting design patterns? :

http://webcache.googleusercontent.com/search?q=cache:SwNgn6VOI4QJ:http://en.wikibooks.org/wiki/C%2B%2B_Programming/Code/Design_Patterns%2Bwikibooks+c%2B%2B+design+patterns&hl=fr&gbv=2&&ct=clnk
Last edited on Feb 13, 2015 at 12:28pm
Feb 13, 2015 at 1:52pm
It looks incomplete. Very little is been told about what problem patterns solve, when to use them and when not to.
For example decorator is best used on classes with no or little data, as each decorator is derived from base class and contains its data, so Ferrari with navigation, car alarm and automatic transmission would have 4 std::string objects, only one of which are actually used.

I suggest to read Classic GoF book Design Patterns: Elements of Reusable Object-Oriented Software.
Also I can recommend Head First Design Patterns.
For quick reference you can use http://sourcemaking.com/
Feb 19, 2015 at 10:24am

Thank you for the links, very useful!
Topic archived. No new replies allowed.