装饰模式简介及实现方式
1. 基本概念
1.1 定义
装饰器模式(Decorator Pattern)又叫做包装模式,允许向一个现有的对象添加新的功能,同时又不改变其结构,是继承关系的一种替换方案
1.2 主要作用
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。一般,扩展一个类都是使用继承的方式,但是随着功能的增多,子类会异常庞大,当有新功能时可能需要修改子类。
1.3 应用场景
在一类对象有多种不同的特性,但又不想通过继承多个类实现时可以用装饰者模式。 比如奶茶,一般有原味奶茶,布丁奶茶,珍珠奶茶,红豆奶茶,甚至双拼奶茶。 如果使用继承机制,那么先要创建父类,原味奶茶,如果要布丁奶茶,那么需要继承原味奶茶再增加布丁。珍珠奶茶同样,创建新的子类添加珍珠。如果双拼的话就是添加两种辅料。 如果使用装饰者模式,先创建奶茶接口,原味奶茶实现奶茶接口就是被装饰类,创建奶茶装饰类接口。创建布丁奶茶装饰类实现奶茶接口,并增加加入布丁的方法。
1.4 相关角色
- 基础接口:一类对象的抽象
- 被装饰类:实现基础接口,完成基础功能
- 抽象装饰类:定义装饰类的变量和方法
- 装饰类:继承抽象装饰类,添加具体实现。
2. 具体代码实现
1.创建一个实体类实现Cloneable接口 奶茶接口
public interface MilkTea {
String getName();
}
原味奶茶实现奶茶接口
public class OriginalMilkTea implements MilkTea{
public String getName(){
return "原味奶茶";
}
}
奶茶抽象装饰类
public abstract class MilkTeaDecorator implements MilkTea{
private MilkTea milkTea;
public MilkTeaDecorator(MilkTea milkTea) {
this.milkTea = milkTea;
}
public String getName(){
String name = this.milkTea.getName();
return name;
}
}
布丁奶茶装饰类
public class PuddingMilkTeaDecorator implements MilkTeaDecorator{
private MilkTea milkTea;
public MilkTeaDecorator(MilkTea milkTea) {
this.milkTea = milkTea;
}
public String getName(){
String name = "布丁"+this.milkTea.getName();
return name;
}
}
珍珠奶茶装饰类
public class PearlMilkTeaDecorator implements MilkTeaDecorator{
private MilkTea milkTea;
public MilkTeaDecorator(MilkTea milkTea) {
this.milkTea = milkTea;
}
public String getName(){
String name = "珍珠"+this.milkTea.getName();
return name;
}
}
具体使用
public class UserDemo{
public static void main(String[] args) {
//原味奶茶
OriginalMilkTea originalMilkTea = new OriginalMilkTea();
// 珍珠奶茶
PearlMilkTeaDecorator pearlMilkTeaDecorator = new PearlMilkTeaDecorator(originalMilkTea);
System.out.println(pearlMilkTeaDecorator.getName());
// 布丁奶茶
PuddingMilkTeaDecorator puddingMilkTeaDecorator = new PuddingMilkTeaDecorator(originalMilkTea);
System.out.println(pearlMilkTeaDecorator.getName());
// 双拼奶茶 多层装饰
PuddingMilkTeaDecorator ShuangPinMilkTeaDecorator = new PuddingMilkTeaDecorator(pearlMilkTeaDecorator);
System.out.println(ShuangPinMilkTeaDecorator.getName());
}
}
3. 优缺点
优点: 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。 比继承更加灵活,符合开闭原则
缺点: 多层装饰比较复杂。