定义: 指在不改变现有对象结构的情况下,动态地增加对象额外功能。属于对象结构型设计模式。
装饰模式的模型角色:
- 抽象产品模型: 具体产品与抽象装饰的父类,一般使用接口定义;
- 具体产品模型: 实现抽象产品,提供抽象产品的具体实现,也是升级产品(具体装饰)基本模型;
- 抽象装饰模型: 实现抽象产品,持有需要升级的产品(具体产品)的实例;
- 具体装饰模型: 具体产品的升级版,有具体产品的功能。继承抽象装饰,提供额外的功能实现。
public interface Food {
/**
* 抽象产品
*/
void make();
}
具体产品使用
public class Bread implements Food {
/**
* 具体产品
*/
@Override
public void make() {
Log.d("TAG", "加水,奶油,面粉");
}
}
抽象装饰类,赋予额外的功能
public abstract class UpFood implements Food {
/**
* 抽象装饰
*/
private Food food;
public UpFood(Food food){
this.food = food;
}
@Override
public void make() {
food.make();
}
}
抽象装饰类的具体实现类(装饰器),添加额外功能的具体实现:
public class AppleBread extends UpFood {
/**
* 具体装饰
*/
public AppleBread(Food food) {
super(food);
}
@Override
public void make() {
//原来功能,不改变
super.make();
add();
}
private void add() {
Log.d("TAG", "加苹果酱");
}
}
最后的使用:
//普通使用(做一个面包)
Food f = new Bread();
f.make();
//装饰使用(做一个苹果酱面包)
Food f2 = new AppleBread(f);
f2.make();
应用场景:
- 需要给一个现有类增加额外功能,而又不能使用继承的方法进行扩充时。
- 对类功能的不确定,能够灵活地增加修改功能。
优点:
- 可以动态的扩展功能,同时也可以选择不同的装饰器实现不同功能,结构灵活。
缺点: - 随着业务的庞大,装饰层过多的话,维护起来比较困难
- 抽象与具体,组件与装饰都是使用继承或实现关系,联系紧密,上层发生改变下层也要随着改变。
小结
在需要给现有类增加额外功能,在不破坏现有类功能结构的情况下有两种选择: 实现或继承现有类。如果继承或者实现的类数量
非常多时,管理起来就比较麻烦,甚至子类直接威胁到父类的功能结构,从而影响到其他的子类。装饰模式巧妙的解决了这一难题。
不是直接继承或者实现这个现有类,而是将额外功能独立出来形成个体,通过持有现有类实例的方式使得现有类与个体类产生联系。
将需要增加的功能比喻成装饰器,现有类就是被装饰。从而达到为现有类添加额外功能的目的,同时不会对现有类产生任何影响,装饰类
可以随时装饰随时放下,灵活性极高。