Decorator Pattern
The Decorator Pattern is a pattern which allows us to attach additional responsibilities to an object dynamically. Decorators provide a flexibility alternative to subclassing for extending functionality.
The Decorator Pattern adds a new Object Oriented Principle to old ones which is:” Classes should be open for extension but closed for modification”. We both know how hard it is to make our code well written debug them without error, that is why this principle tells us that once well written it shouldn’t be modified, but could be used by other classes by extension.
In this pattern we can see that composition and delegation can be used to add new behaviors at runtime which give us more flexibility to add or remove characteristics of an object by a set of classes that are used to wrap the main object. The number of small object or classes should be limited otherwise the overuse might be complex.
Let’s illustrate this pattern by an example of a coffee beverage.
package com.decorator.pack1;
/**
* This class is an abstract one which will be used to set and get description
* @author Pascal
*
*/
public abstract class Beverage {
String description = "Unknown Beverage";
/**
* This method return the description of this class
* @return: String description
*/
public String getDescription(){
return description;
}
/*
* Set the price of the beverage
*/
public abstract double cost();
}
package com.decorator.pack1;
/**
* This class has the duty to get the wrapper(or decorator) description
* @author Pascal
*
*/
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
package com.decorator.pack1;
/**
* Is A Beverage class by inheritance
* @author Pascal
*
*/
public class DarkRoast extends Beverage{
public DarkRoast(){
description = "DarkRoast";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return .99;
}
}
package com.decorator.pack1;
/**
* Is A Beverage class by inheritance
* @author Pascal
*
*/
public class Decaf extends Beverage{
public Decaf(){
description = "Decaf";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 1.05;
}
}
package com.decorator.pack1;
/**
* Is A Beverage class by inheritance
* @author Pascal
*
*/
public class Espresso extends Beverage{
public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
package com.decorator.pack1;
/**
* Is A Beverage class by inheritance
* @author Pascal
*
*/
public class HouseBlend extends Beverage{
public HouseBlend(){
description = "HouseBlend coffee";
}
@Override
public double cost() {
return 0.89;
}
}
package com.decorator.pack1;
/**
* IS A CondimentDecorator
* @author Pascal
*
*/
public class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",Mocha";
}
@Override
public double cost() {
return 0.20+beverage.cost();
}
}
package com.decorator.pack1;
/**
* IS A CondimentDecorator
* @author Pascal
*
*/
public class Soy extends CondimentDecorator{
Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+", Soy";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.15 +beverage.cost();
}
}
package com.decorator.pack1;
/**
* IS A CondimentDecorator
* @author Pascal
*
*/
public class SteamedMilk extends CondimentDecorator{
Beverage beverage;
public SteamedMilk(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+", Steamed Milk";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.10+beverage.cost();
}
}
package com.decorator.pack1;
/**
* IS A CondimentDecorator
* @author Pascal
*
*/
public class Whip extends CondimentDecorator{
public Beverage beverage;
public Whip(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+", whip";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.10+ beverage.cost();
}
}
package com.decorator.pack1;
/**
* This is the main class for this project, which means the order
* @author Pascal
*
*/
public class StarbuzzCoffee {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription()+" $"+beverage.cost());
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()+" $"+beverage2.cost());
Beverage beverage3 = new HouseBlend();
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);
System.out.println(beverage3.getDescription()+" $"+beverage3.cost());
}
}
分享到:
相关推荐
the Decorator Pattern (装饰器与装饰器模式) - **概念区别**:装饰器是一种语言特性,而装饰器模式是设计模式之一。 - **应用场景**:装饰器更适用于函数和类级别的增强,而装饰器模式适用于对象的动态包装。 ###...
在本资源“the code of Design Pattern”中,我们很可能会找到有关如何在C++编程语言中实现各种设计模式的代码示例。 设计模式分为三类:创建型、结构型和行为型。创建型模式关注对象的创建过程,如单例(Singleton...
Each pattern is introduced with a non-technical example or story that illustrates the pattern concept. The details are described with Java code examples and UML diagrams. Each pattern description ...
After reading this book, you will be able to convincingly leverage these design patterns (factory pattern, builder pattern, prototype pattern, adapter pattern, facade pattern, decorator pattern, ...
- Decorator pattern adds behavior or responsibilities to an object dynamically without affecting the behavior of other objects in the same class. - Facade pattern provides a simplified interface to a ...
Learn how to implement design patterns in Java: each pattern in Java Design Patterns is a complete implementation and the output is generated using Eclipse, making the code accessible to all. The ...
Technical and architect of YSlow 2.0, the web page performance optimization tool -- JavaScript Patterns includes practical advice for implementing each pattern discussed, along with several hands-on ...
<decorator name="default" page="default-decorator.jsp"> <pattern>/*</pattern> </decorator> ``` 这里的`default-decorator.jsp`是装饰器页面。 ### Sitemesh使用示例 在提供的压缩包文件中,有多个...
本资料"Swift DesignPattern"包含了一些Swift语言中的常见设计模式实例,下面我们将详细探讨这些设计模式及其在Swift中的应用。 1. **单例模式(Singleton)**:单例模式确保一个类只有一个实例,并提供全局访问点...
Decorator Facade Flyweight Private Class Data Proxy Behavioral patterns Chain of Responsibility Command Interpreter Iterator Mediator Memento Null Object Observer State Strategy Template Method ...
With Head First Design Patterns, you'll avoid the embarrassment of thinking Decorator is something from the 'Trading Spaces' show. Best of all, in a way that won't put you to sleep! We think your ...
Title: Test-Driven Development with Python, 2nd Edition Length: 592 pages ... The Token Social Bit, the Page Pattern, and an Exercise for the Reader Chapter 26. Fast Tests, Slow Tests, and Hot Lava
2. **装饰器模式(Decorator Pattern)**:动态地给对象添加新的行为或职责,允许在运行时增加功能,同时保持接口不变。 3. **工厂模式(Factory Pattern)**:提供一个创建对象的接口,但由子类决定实例化哪个类,...
此外,"Java Present and Future"、"The Decorator Design Pattern in Depth"、"Fix This" 等文章深入探讨了Java的不同方面,如装饰者设计模式的深入分析,以及提供给中高级测试问题的"Fix This"部分。 整体上,...
### 装饰器模式(Decorator Pattern) 装饰器模式动态地给一个对象添加一些额外的职责。在JavaScript中,可以通过创建一个包装器对象来扩展原对象的功能,而不改变其结构。 ### 代理模式(Proxy Pattern) 代理...
装饰器模式(decorator-pattern)享元模式(flyweight-pattern)观察者模式(observer-pattern)代理模式(proxy-pattern)责任链模式(responsibility-chain-pattern)状态模式(state-pattern)策略模式(s