装饰模式是一种设计模式,在不需要更改原有类文件和使用继承的情况下,能够动态地扩展一个对象的功能。这种模式通过创建一个包装对象,即装饰者,来封装实际的对象。
装饰模式,又称Decorator Pattern,是23种设计模式之一。它允许在运行时动态地向一个对象添加新的行为,而不必修改原有的类。装饰模式通过创建一个包装对象,即装饰者,来封装实际的对象。
装饰对象与真实对象具有相同的接口,这使得客户端对象能够以与真实对象相同的方式与装饰对象交互。
装饰对象包含一个指向真实对象的引用。
装饰对象接收来自客户端的所有请求,并将其转发给真实对象。
在转发请求之前或之后,装饰对象可以添加额外的功能,从而无需修改给定对象的结构即可在运行时添加功能。在面向对象的设计中,通常通过继承来实现对给定类的功能扩展。
装饰模式适用于以下场景:
1. 需要扩展一个类的功能,或为其添加附加职责。
2. 动态地为一个对象添加功能,且这些功能可以随时取消。
3. 增加由基本功能组成的大量功能,使继承关系变得不切实际。
4. 当无法通过子类化来扩展时,如当类定义被隐藏,或类定义不能用于生成子类时。
装饰模式提供了比继承更灵活的方式来扩展对象的功能。
通过使用不同的具体装饰类及其组合,设计师可以创造多种不同的行为组合。
装饰模式的灵活性也带来了更高的复杂度。
过度使用装饰模式可能导致程序结构变得复杂。
应优先考虑组合而非继承。
类的设计应该对扩展开放,对修改封闭。
若只有一个具体的Component类,则让Decorator继承该类。
若只有一个具体的Decorator类,则可以将Decorator和混凝土 Decorator合并。
新职责方面,适配器模式也能在转换时增加新职责,但其主要目的是转换接口,而装饰模式的主要目的是为被装饰者增加新职责。
接口方面,适配器模式使用新接口调用原接口,原接口对于新系统来说是不可见的;而装饰模式保持原接口不变,系统通过原接口使用装饰对象。
包裹对象方面,适配器了解被适配者的细节,而装饰者只知其接口,具体类型则在运行时确定。
Java IO流是装饰模式的一个典型例子。
在装饰模式中,涉及的角色包括:
抽象构件(Component)角色:定义一个接口,规范准备接收附加责任的对象。
具体构件(混凝土 Component)角色:定义一个将要接收附加责任的类。
装饰(Decorator)角色:持有构件(Component)对象的实例,并实现与抽象构件接口一致的接口。
具体装饰(Concrete Decorator)角色:负责为构件对象添加附加的责任。
以下示例展示了如何使用装饰模式来扩展现有类的功能。其中,ThirdParty.Java表示一个已有的或第三方的功能,由于某些原因无法直接修改,它提供了一个sayMsg()方法。现在我们要在sayMsg()方法中添加一些额外的信息,因此我们编写了一个Decorator.java类。MailTest.java是客户端测试程序。
```java
// IthirdParty.Java--抽象接口类
package decorator.saystr;
public 接口 IThirdParty {
public String sayMsg();
}
// ThirdParty.Java--具体类
public class ThirdParty implements IThirdParty {
public String sayMsg() {
return "hello";
}
}
// Decorator1.java 具体装饰类1
package decorator.saystr;
public class Decorator1 implements IThirdParty {
private IThirdParty thirdParty;
public Decorator1(IThirdParty thirdParty) {
this.thirdParty = thirdParty;
}
public String sayMsg() {
return "##1" + thirdParty.sayMsg() + "##1";
}
}
// Decorator2.java 具体装饰类2
package decorator.saystr;
public class Decorator2 implements IThirdParty {
private IThirdParty thirdParty;
public Decorator2(IThirdParty thirdParty) {
this.thirdParty = thirdParty;
}
public String sayMsg() {
return "##2" + thirdParty.sayMsg() + "##2";
}
}
// MailTest.java
package decorator.saystr;
public class MailTest {
public static void main(String[] args) {
IThirdParty thirdPartyOne = new ThirdParty();
IThirdParty decorator1 = new Decorator1(thirdPartyOne);
IThirdParty decorator2 = new Decorator2(decorator1);
System.out.println(decorator2.sayMsg());
}
}
```
执行结果为:`##2##1hello##1##2`
设计模式之装饰模式(Decorator).博客园.2024-11-04
23种设计模式之装饰者(Decorator)模式.掘金开发者社区.2024-11-04
3.装饰模式.Graphic Design Patterns.2024-11-04
Copyright © 1996-2025 DaHe Network Media. Group All Rights Reserved