装饰器模式是一种软件设计模式,它的核心思想是在不改变原有对象的情况下,动态地增加对象的功能,同时也能够分离出这些功能,使系统更加灵活。在本文中,我们将讨论装饰器模式的类图结构,包括如何实现装饰器模式以及其在软件开发中的应用。
类图结构
装饰器模式由四个角色构成,分别是抽象构件(Component)、具体构件(ConcreteComponent)、抽象装饰器(Decorator)和具体装饰器(ConcreteDecorator)。下面我们将分别介绍这四个角色。
1. 抽象构件(Component)
抽象构件是一个接口或抽象类,它定义了被装饰的对象的行为。它有两个重要的作用,一是为具体构件和具体装饰器定义一致的接口,以便能够在任何装饰器中使用它;二是定义一个接口,使得用户可以使用具体构件对象或者具体装饰器对象。
2. 具体构件(ConcreteComponent)
具体构件是实现抽象构件接口的具体类,它是被装饰的原始对象,该对象就是被动态地修饰的对象。
3. 抽象装饰器(Decorator)
抽象装饰器是一个接口或抽象类,它继承了抽象构件接口,并持有一个指向抽象构件的引用,这样就可以保证所有的装饰器都具有抽象构件的行为。
4. 具体装饰器(ConcreteDecorator)
具体装饰器是实现抽象装饰器接口,它继承了抽象装饰器,并在内部持有一个指向抽象构件的引用,在装饰时可以动态地增加一些额外的行为。
实现装饰器模式
下面我们通过一个简单的例子来演示如何实现装饰器模式。假设我们有一个咖啡店,我们希望动态地增加咖啡的调料,例如牛奶、糖浆、巧克力酱等。首先我们定义抽象构件(ICoffee):
```
public interface ICoffee {
public double getCost();
public String getDescription();
}
```
然后定义具体构件(Espresso, Americano等):
```
public class Espresso implements ICoffee {
public double getCost() {
return 1.99;
}
public String getDescription() {
return "Espresso Coffee";
}
}
```
接着,定义抽象装饰器(Decorator):
```
public abstract class Decorator implements ICoffee {
protected ICoffee coffee;
public Decorator(ICoffee coffee) {
this.coffee = coffee;
}
public double getCost() {
return coffee.getCost();
}
public String getDescription() {
return coffee.getDescription();
}
}
```
其中,抽象装饰器持有一个指向抽象构件的引用,这样就可以保证所有的装饰器都具有抽象构件的行为。
最后,定义具体装饰器(Milk, Syrup等):
```
public class Milk extends Decorator {
public Milk(ICoffee coffee) {
super(coffee);
}
public double getCost() {
return super.getCost() + 0.5;
}
public String getDescription() {
return super.getDescription() + ", Milk";
}
}
```
具体装饰器继承了抽象装饰器,并在其内部持有一个指向抽象构件的引用,在装饰时可以动态地增加一些额外的行为。例如Milk装饰器通过调用super.getCost()获取原来咖啡的费用,并增加0.5来计算加入牛奶后的咖啡费用。
最后,我们可以使用装饰器对具体构件(Espresso, Americano等)进行装饰。例如:
```
ICoffee c1 = new Espresso();
c1 = new Milk(c1);
System.out.println(c1.getDescription() + " " + c1.getCost());
```
输出结果:
```
Espresso Coffee, Milk 2.49
```
应用场景
装饰器模式常用于以下场景:
1. 在不改变原有对象的情况下,动态地增加对象的功能。例如上述例子,我们可以在不改变原有Espresso对象的情况下动态地增加牛奶、糖浆等调料。
2. 需要灵活地组合对象,以满足不同的需求。例如可以组合多个具体装饰器来满足用户不同的需求。
3. 在不确定对象的具体行为时,可以使用装饰器来增加额外的行为。例如在某些情况下,我们无法确定具体构件的行为,可以使用装饰器来增加一些额外的行为。
扫码咨询 领取资料