Design Pattern: Decorator

Decorator (http://en.wikipedia.org/wiki/Decorator_pattern,aka, also known as Wrapper, an alternative naming shared with the Adapter pattern) is a structural pattern that allowsadding new behavior/functionality to an individual object atrun time, without affecting the behavior of objects from the same class.

  • subclass from Component class

  • in Decorator class add pointer of Component as its data member

  • in Decorator class’ ctor, pass in Component pointer to initialize this data member

  • in Decorator class, redirect all of its methods to “Component”  pointer

  • in ConcreteDecorator, override any Component’s methods that needs to be modified




600px-Decorator_UML_class_diagram.svg.png


Alternative, subclassing, which add behavior at compile time, would result in exponential rise of new classes

  • This difference becomes most important when there areseveralindependent ways of extending functionality. Subclassing would mean that a new class would have to be made for every possible combination. By contrast, decorators are objects, created at runtime, and can be combined on a per-use basis


600px-UML2_Decorator_Pattern.png


For example, if we have window class and wants to add scrollbar on window. At this point there is no real difference to add subclass scrollingWindow  or have a decorator scrollingWindowDecorator. But what if we want to add border to ALL windows, then we have to create sublcass windowWithBoarder and scrollingWindowWithBoarder. Things will get worse with every new feature added.


#include "stdafx.h"
#include <string>
#include <iostream>
 
// abstract class define the functionalities, some of which will be modified by decorator
class Coffee
{
public:
	virtual double cost() = 0;
	virtual std::string getIntegridient() = 0;
	virtual ~Coffee() {
	}
	virtual void print() {
		std::cout << "Cost: " << cost() << "Integridient: " << getIntegridient() << std::endl;
	}
};
 
// concrete class without any extra integridient
class SimpleCoffee : public Coffee
{
public:
	virtual double cost() {
		return 1;
	}
 
	virtual std::string getIntegridient() {
		return "simple coffee";
	}
};
 
// Decorators
class Decorator : public Coffee
{
public:
	Decorator(Coffee* c) 
		: basicCoffee_(c) {
	}
 
	virtual double cost() {
		return basicCoffee_->cost();
	}
 
	virtual std::string getIntegridient() {
		return basicCoffee_->getIntegridient();
	}
private:
	Coffee *basicCoffee_;
};
 
 
class MilkDecorator : public Decorator
{
public:
	MilkDecorator(Coffee *c)
		: Decorator(c) {
	}
 
	virtual double cost() {
		return Decorator::cost() + 0.5;
	}
 
	virtual std::string getIntegridient() {
		return "Milk, " + Decorator::getIntegridient() ;
	}
};
 
class WhipCoffee : public Decorator
{
public:
	WhipCoffee(Coffee *c) 
		: Decorator(c) {
	}
 
	virtual double cost() {
		return Decorator::cost() + 1;
	}
 
	virtual std::string getIntegridient() {
		return "Whip, " + Decorator::getIntegridient() ;
	}
};
 
 
int _tmain(int argc, _TCHAR* argv[])
{
 
	SimpleCoffee s;
	s.print();
 
	// decorated seperately
	MilkDecorator m(&s);
	m.print();
 
	WhipCoffee w(&s);
	w.print();
	
	// test combinations
	WhipCoffee wm(&m);
	wm.print();
 
	MilkDecorator mw(&w);
	mw.print();
 
	// is this desirable ?
	MilkDecorator mm(&m);
	mm.print();
 
	return 0;
}


// Decorator2.cpp : another simple decorator example
//

#include "stdafx.h"
#include <iostream>
#include <string>

// base class
class Window
{
public:
    virtual void draw() = 0;
    virtual std::string getDescription() = 0;
    
    virtual ~Window() {
    }

    virtual void print() {
        std::cout << "DESCRIPTION: " << getDescription() << std::endl;
        draw();
    }
};

// (existing) concrete class
class SimpleWindow : public Window
{
public:
    virtual void draw() {
        std::cout << "Simple draw" << std::endl;
    }

    virtual std::string getDescription() {
        return "Simple Window";
    }
};

// decorators for Window classes, including the decorators themself
class Decorator : public Window
{
public:
    Decorator(Window *w)
        :win_(w) {
    }

    virtual void draw() {
        win_->draw();
    }

    virtual std::string getDescription() {
        return win_->getDescription();
    }

private:
    Window *win_;
};

class ScrollBarDecorator : public Decorator
{
public:
    ScrollBarDecorator(Window *w)
        : Decorator(w) {
    }

    virtual void draw() {
        drawScrollBar();
        Decorator::draw();
    }

    virtual std::string getDescription() {
        return "scroll bar " + Decorator::getDescription();
    }

private:
    void drawScrollBar() {
        std::cout<< "draw scroll bar " << std::endl;
    }

};

class BoarderDecorator : public Decorator
{
public:
    BoarderDecorator(Window *w)
        :Decorator(w) {
    }

    virtual void draw() {
        drawBoarder();
        Decorator::draw();
    }

    virtual std::string getDescription() {
        return "boarder " + Decorator::getDescription();
    }
private:
    void drawBoarder() {
        std::cout << "draw boarder " << std::endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    SimpleWindow sw;
    sw.print();

    ScrollBarDecorator sbsw(&sw);
    sbsw.print();

    BoarderDecorator bdsw(&sw);
    bdsw.print();

    BoarderDecorator bdsb(&sbsw);
    bdsb.print();

    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值