目录
一、代码世界的 “魔法道具”
在代码的奇妙世界里,你是否曾渴望拥有一种神奇的工具,能在不改变原有代码结构的基础上,为程序轻松增添新功能?装饰器模式,就如同这样一个神奇的 “魔法道具”,能让你的代码实现华丽升级 !它可以在运行时动态地为对象添加新的行为,而无需修改对象的原有代码,就像给你的代码穿上一件件功能各异的 “魔法披风”,让它拥有更多超能力。今天,就让我们一起走进装饰器模式的奇幻世界,揭开它神秘的面纱!
二、装饰器模式初相识
2.1 装饰器模式是什么
装饰器模式是一种结构型设计模式,它允许你在不改变对象结构的前提下,动态地给对象添加新的功能 。与继承不同,继承是在编译时静态地扩展类的功能,而装饰器模式是在运行时动态地为对象添加功能,更加灵活。
2.2 生活中的装饰器模式
为了更好地理解装饰器模式,让我们先来看看生活中的例子。你去奶茶店买奶茶,基础款的奶茶可能只有茶和奶,但你可以根据自己的喜好添加各种小料,如珍珠、椰果、布丁、红豆等。每添加一种小料,奶茶就多了一种新的口感和味道,这就是装饰器模式在生活中的体现 。
在这个例子中,基础奶茶就是被装饰的对象,而各种小料就是装饰器,它们为基础奶茶添加了不同的功能(口感和味道)。而且,你可以自由选择添加哪些小料,添加多少,这就体现了装饰器模式的动态性和灵活性。
三、装饰器模式的构成
装饰器模式主要包含四个角色:抽象构件(Component)、具体构件(ConcreteComponent)、抽象装饰器(Decorator)和具体装饰器(ConcreteDecorator)。下面我们结合 Java 代码来详细了解一下这四个角色。
3.1 抽象构件(Component)
抽象构件是被装饰对象的原始定义,它可以是一个接口或者抽象类,规定了被装饰对象的行为。在 Java 中,以创建一个表示 “饮料” 的抽象构件为例:
// 抽象构件:饮料
public interface Beverage {
// 获取饮料描述
String getDescription();
// 获取饮料价格
double getCost();
}
在这个例子中,Beverage接口定义了两个方法:getDescription用于获取饮料的描述,getCost用于获取饮料的价格 。所有具体的饮料类(如咖啡、茶等)都需要实现这个接口,以保证它们具有统一的行为规范。这就好比所有的饮料都应该有名称和价格,这样我们在操作饮料对象时,就可以通过这些统一的方法来获取相关信息 。
3.2 具体构件(ConcreteComponent)
具体构件是抽象构件的具体实现,它是被装饰的对象,实现了抽象构件中定义的方法,提供了最基本的功能 。继续上面的例子,我们创建一个具体的饮料类 “咖啡” 来实现Beverage接口:
// 具体构件:咖啡
public class Coffee implements Beverage {
@Override
public String getDescription() {
return "咖啡";
}
@Override
public double getCost() {
return 10.0;
}
}
在这个Coffee类中,我们实现了Beverage接口的getDescription和getCost方法,分别返回 “咖啡” 和价格 10.0 。这就好比我们有了一杯最基础的咖啡,它有自己的名称和价格,这是它的基本属性和功能 。
3.3 抽象装饰器(Decorator)
抽象装饰器继承或实现了抽象构件,它内部有一个指向抽象构件的属性,用于扩展具体构件的功能。抽象装饰器通常会提供一个构造函数,用于接收一个抽象构件类型的对象,并将其赋值给内部的属性 。在 Java 中,我们创建一个抽象装饰器类 “饮料装饰器”:
// 抽象装饰器:饮料装饰器
public abstract class BeverageDecorator implements Beverage {
protected Beverage beverage;
public BeverageDecorator(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription();
}
@Override
public double getCost() {
return beverage.getCost();
}
}
在这个BeverageDecorator类中,我们定义了一个Beverage类型的属性beverage,并通过构造函数将传入的Beverage对象赋值给它 。同时,我们重写了getDescription和getCost方法,默认情况下,这些方法会调用被装饰对象(beverage)的相应方法,以保证装饰器不会改变被装饰对象的原有行为 。抽象装饰器就像是一个通用的装饰框架,它为具体装饰器提供了一个基础结构,具体的装饰逻辑将在具体装饰器中实现 。