装饰模式

6
1
收藏
分享

装饰模式是一种设计模式,在不需要更改原有类文件和使用继承的情况下,能够动态地扩展一个对象的功能。这种模式通过创建一个包装对象,即装饰者,来封装实际的对象。

定义

装饰模式,又称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

评论 1
User avatar
重生62687
谢谢博主主的分享,期待更多精彩的比赛情报!
回复

Copyright © 1996-2025 DaHe Network Media. Group All Rights Reserved

京ICP备2023013984号

抖运营雅思百科