装饰器模式定义:动态地将责任附加到对象上,若要扩展功能,装饰器提供了比继承更有弹性的替代方案
上例子,咖啡店现有几种咖啡,超优深焙(DarkRoast),无咖啡因咖啡(Decaf),浓咖啡(Espresso),有几种调料,牛奶(Milk),摩卡(Mocha),豆浆(Soy)
咖啡可以加任意调料,变化的可能有:咖啡种类,调料种类,调料价格
基于设计原则:类应该对扩展开放,对修改关闭,所以这些变化最好可以是动态去改变,这时候装饰器也就派上了用场
现上代码,再将原理:
/**
* 饮料,店内所有提供的饮料都必须继承此类
*/
public abstract class Beverage {
String description = "Unknown Beverage";
/**
* 由其子类描述饮料,例如:超优深焙(DarkRoast)
*/
public String getDescription() {
return description;
}
/**
* 价格,子类必须定义自己的实现
*/
public abstract double cost();
}
/**
* 调味装饰器
*/
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
/**
* 超优深焙
*/
public class DarkRoast extends Beverage {
public DarkRoast() {
description = "Dark Roast Coffee";
}
public double cost() {
return .99;
}
}
/**
* 无咖啡因咖啡
*/
public class Decaf extends Beverage {
public Decaf() {
description = "Decaf Coffee";
}
public double cost() {
return 1.05;
}
}
/**
* 浓咖啡
*/
public class Espresso extends Beverage {
public Espresso() {
description = "Espresso";
}
public double cost() {
return 1.99;
}
}
/**
* 加牛奶
*/
public class Milk extends CondimentDecorator {
Beverage beverage;
public Milk(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Milk";
}
public double cost() {
return .10 + beverage.cost();
}
}
/**
* 摩卡
*/
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
public double cost() {
return .20 + beverage.cost();
}
}
/**
* 豆浆
*/
public class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Soy";
}
public double cost() {
return .15 + beverage.cost();
}
}
/**
* 覆盖奶泡
*/
public class Whip extends CondimentDecorator {
Beverage beverage;
public Whip(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Whip";
}
public double cost() {
return .10 + beverage.cost();
}
}
/**
* 咖啡点测试类
*/
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());
}
}
OK,可以看出来装饰器的特点可有分为一下5个部分:
- 装饰者和被装饰者对象有相同的超类(都继承Beverage)
- 你可以用一个或者多个装饰者包装一个对象
- 因为有相同超类,所以可以在anywhere and anytime 用装饰过的对象代替被装饰者,即可以在运行时动态地装饰对象
-
装饰者可以在所委托的被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的----------装饰器模式的用途
总结:明白了装饰器,在来看java.io.*,似乎可以更好的理解了,所谓装饰就是继承共同父类,然后包装,变化其行为
那就再贴个自己实现java.io的装饰器,代码如下:
/**
* 将所有字节转换为小写
*/
public class LowerCaseInputStream extends FilterInputStream {
public LowerCaseInputStream(InputStream in) {
super(in);
}
public int read() throws IOException {
int c = super.read();
//转换为小写
return (c == -1 ? c : Character.toLowerCase((char)c));
}
public int read(byte[] b, int offset, int len) throws IOException {
int result = super.read(b, offset, len);
for (int i = offset; i < offset+result; i++) {
//转换为小写
b[i] = (byte)Character.toLowerCase((char)b[i]);
}
return result;
}
}
/**
* io装饰器测试类
*/
public class InputTest {
public static void main(String[] args) throws IOException {
int c;
try {
InputStream in =
new LowerCaseInputStream(
new BufferedInputStream(
new FileInputStream("test.txt")));
while((c = in.read()) >= 0) {
System.out.print((char)c);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
OK,至此装饰其模式结束,装饰器也有其缺点:
1,加入大量的装饰类,如IO包一样,初看之时很是头晕,不过这点貌似没什么办法,有利就有弊嘛,呵呵。。。
2,增加了代码的难度,需要new很多对象,这点应该可以利用工厂(Factory)模式和生成器(Builder)模式一些问题
分享到:
相关推荐
c++设计模式-结构型模式-装饰器模式;QT工程;c++简单源码; 装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
结构型模式如适配器模式(Adapter)、装饰器模式(Decorator)和代理模式(Proxy),则关注如何组合和连接类与对象,以达到新的功能。行为型模式如观察者模式(Observer)、策略模式(Strategy)和访问者模式...
Java 设计模式 - 装饰器模式 装饰器模式(Decorator Pattern)是一种结构性设计模式,它允许您在不影响同一类的其他对象的行为的情况下,静态或动态地向单个对象添加行为。该模式非常有用,当您想要在运行时添加或...
设计模式通常分为三类:创建型模式(如工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式),结构型模式(如适配器模式、装饰器模式、代理模式、桥接模式、组合模式、外观模式、享元模式)以及行为型模式(如...
Spring 设计模式之装饰器模式详解 在软件设计中,经常会遇到需要在不修改原有代码的情况下,添加新的功能或行为。这时,装饰器模式便可以发挥其作用。在 Spring 设计模式中,装饰器模式是非常重要的一种设计模式。 ...
4. **装饰器模式** - QT4的QProxyStyle和QCommonStyle可以看作装饰器模式的实例,它们允许开发者自定义控件的外观而无需修改原有代码。 5. **策略模式** - QT4的信号和槽可以视为一种策略,开发者可以根据需要连接...
代理模式(Proxy Pattern)、单例模式(Singleton Pattern)、工厂方法...装饰模式(Decorator Pattern)、迭代器模式(Iterator Pattern)、组合模式(Composite Pattern)、观察者模式(Observer Pattern)、责任链...
设计模式是软件工程中的一种最佳实践,用于解决在软件开发过程中常见的问题。这些模式是由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位大师,通常被称为GoF(Gang of Four),在他们的经典著作...
装饰模式是一种结构型设计模式,它允许在运行时动态地给对象添加新的行为或职责,同时保持对象的接口不变。这种模式使得我们可以在不修改原有代码的基础上,通过组合不同的装饰来扩展对象的功能,实现了代码的高可...
## 一、概述 装饰器模式允许在不修改对象现有... - 在面向对象编程中,装饰器模式是一种设计模式,它允许静态或动态地向单个对象添加行为,而不会影响同一类的其他对象的行为。装饰器模式通常对于遵循单一职责原则非
这个资源"Java设计模式----通俗易懂版"显然是一个专门针对初学者或需要深入理解设计模式的开发者编写的指南。作者以形象生动的例子解释了23种经典的Java设计模式,使得复杂的概念变得更加易于理解。 首先,我们要...
装饰模式(Decorator Pattern)是一种结构型设计模式,其主要目的是在不改变对象自身的基础上,在运行时为对象添加新的行为或属性。它通过包装原有对象,而不是通过继承来扩展功能,从而提供了更大的灵活性,避免了...
装饰者模式是一种结构型设计模式,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码或创建子类。这种模式的核心思想是通过将对象封装在一个装饰器对象内,来扩展对象的功能,同时保持原有接口的不变...
2. **设计模式分类**:设计模式通常分为三类:创建型模式(如工厂方法、抽象工厂、单例、建造者、原型)、结构型模式(如适配器、桥接、装饰、组合、代理、外观、享元)和行为型模式(如责任链、命令、解释器、迭代...
设计模式包括创建型模式(如单例、工厂方法、抽象工厂等)、结构型模式(如适配器、装饰器、代理等)和行为型模式(如策略、观察者、职责链等)。这些模式提供了良好的可复用性和可扩展性,帮助开发者遵循“开闭原则...
包括适配器模式(Adapter)、桥接模式(Bridge)、装饰器模式(Decorator)、外观模式(Facade)、组合模式(Composite)、享元模式(Flyweight)和代理模式(Proxy)。这些模式可以帮助我们更好地组织代码,实现...
设计模式07-组合模式、装饰模式 设计模式09-外观模式、享元模式 设计模式10-代理模式、结构型模式大复习 设计模式11-行为模式-责任链、命令模式 设计模式12-解释器模式 设计模式13-迭代器模式 设计模式14-中介者模式...
"装饰器模式"可能用于增加或修改对象的功能,例如在画笔程序中,用户可能需要改变线条的颜色、宽度等属性。装饰器模式可以在运行时动态地给对象添加新的行为,而无需修改原有代码,使得代码结构更灵活。 "组合模式...
结构型模式则关注如何将类或对象组合成更大的结构,例如适配器模式(Adapter)、装饰器模式(Decorator)、代理模式(Proxy)、桥接模式(Bridge)和组合模式(Composite)。这些模式可以帮助我们处理类与类之间的...