design_pattern_decorator

This post implements decorator pattern in <Head First Design Pattern>. Decorator Pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible  alternative to subclassing for extending functionality. Similar withInheritance,  decorators allow behavior to be extended without the need to modify existing code. Decorators have the same type as the components they decorate, yet change the behavior of their components by adding new functionality before or after method calls to the component.

  1. Ensure the context is: a single core (or non-optional) component,several optional embellishments or wrappers, and an interface that iscommon to all.
  2. Create a "Lowest Common Denominator" interface that makes allclasses interchangeable.
  3. Create a second level base class (Decorator) to support theoptional wrapper classes.
  4. The Core class and Decorator class inherit from the LCD interface.
  5. The Decorator class declares a composition relationship to the LCDinterface, and this data member is initialized in its constructor.
  6. The Decorator class delegates to the LCD object.
  7. Define a Decorator derived class for each optional embellishment.
  8. Decorator derived classes implement their wrapper functionality -and - delegate to the Decorator base class.
  9. The client configures the type and ordering of Core and Decoratorobjects.

The general class diagram is given by

The component class is an abstract class, providing uniform interface to use method A and method B.ConcreteComponent implements the general blueprint. Suppose we want some newBehavior(), at the meantime, we do not want to open the class the revise the code for ConcreteComponent, we could useConcereteDecotor, whose general definition is provided by abstract classDecorator. For the specific coffee price in the book, the class structure is shown below

The code for basic beverage is given by

class Beverage {
public:
    Beverage(){ description = "Unknown Beverage!"; }
    virtual ~Beverage() {}

    virtual std::string getDescription() const { return description; }
	virtual double cost() const = 0;
protected:
    std::string description;
};

/* Basic Cofee Types Inherits Beverage
HouseBlend, DarkRoast, Espresso, Decaf */
class HouseBlend : public Beverage{
public:
    HouseBlend() { description = "House Blend Coffee"; }
    virtual double cost() const { return 0.89; }
};

class DarkRoast : public Beverage{
public:
    DarkRoast() { description = "Dark Roast Coffee"; }
    virtual double cost() const { return 0.99; }
};

class Espresso : public Beverage{
public:
    Espresso() { description = "Espresso Coffee"; }
    virtual double cost() const { return 1.99; }
};

class Decaf : public Beverage{
public:
    Decaf() { description = "Decaf Coffee"; }
    virtual double cost() const { return 1.05; }
};

The code for condiments is given by

class CondimentDecorator : public Beverage {
public:
    CondimentDecorator() {
        beverage = NULL;
    }

    CondimentDecorator(const Beverage* beverage_){
		beverage = beverage_;
	}

	CondimentDecorator(const CondimentDecorator* cd){
        this->beverage = cd->beverage;
	}

	void operator=(const CondimentDecorator* cd){
        this->beverage = cd->beverage;
	}

	virtual ~CondimentDecorator(){
        delete beverage;
		beverage = NULL;
	}

	virtual std::string getDescription() const = 0;

protected:
    const Beverage* beverage;
};

class Milk : public CondimentDecorator {
public:
    Milk():CondimentDecorator(){}

    Milk(const Beverage* beverage_):CondimentDecorator(beverage_){}

	~Milk() {
		delete beverage;
		beverage = NULL;
	}

 	std::string getDescription() const {
		return beverage->getDescription() + ", Milk";
	}

 	double cost() const {
		return 0.10 + beverage->cost();
	}
};

The main function calculates Espresso, Espresso+Milk, Espresso+Double Milk

#include <iostream>
#include <./beverage.hpp>

int main()
{
    Beverage* beverage1 = new Espresso();
    std::cout << beverage1->getDescription() << " $" << beverage1->cost() << std::endl;

    Beverage* beverage2 = new Milk(beverage1);
    std::cout << beverage2->getDescription() << " $" << beverage2->cost() << std::endl;

    Beverage* beverage3 = new Milk(beverage2);
    std::cout << beverage3->getDescription() << " $" << beverage3->cost() << std::endl;

    return 0;
}
The result is



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值