主要讲解装饰器Decoration模式。
突然想写这个设计模式,是因为刚看了FactoryBean,因为它通过装饰模式,来进一步修饰Bean对象,所以想看看这个模式是怎么使用的。我理解这个设计模式,就是基于原来的对象进行装饰。
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
使用场景:
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
先定义一个Food的抽象类:
public abstract class Food {
protected String desc;
public abstract String getDesc();
}
然后实例化2个实物对象,比如鸡肉和鸭肉:
public class Chicken extends Food {
public Chicken() {
this.desc = "鸡肉";
}
@Override
public String cook() {
return this.desc;
}
}
public class Duck extends Food {
public Duck() {
this.desc = "鸭肉";
}
@Override
public String cook() {
return this.desc;
}
}
再定义一个装饰的抽象类,这个是继承了Food:
public abstract class FoodDecoration extends Food {
@Override
public abstract String cook();
}
再定义两个不同的装饰类,一个是烤,一个是蒸:
public class RoastFood extends FoodDecoration {
private Food food;
public RoastFood(Food f){
this.food = f;
}
@Override
public String cook() {
return getDecoration() + food.cook();
}
private String getDecoration(){
return "烤";
}
}
public class SteamedFood extends FoodDecoration{
private Food food;
public SteamedFood(Food food) {
this.food = food;
}
private String getDecoration() {
return "蒸";
}
@Override
public String cook() {
return this.getDecoration() + food.cook();
}
}
最后我们可以对实物进行装饰:
public static void main(String args[]) {
// 测试单纯的食物
Chicken chicken = new Chicken();
System.out.println(chicken.cook());
// 测试单重修饰的食物
RoastFood roastFood = new RoastFood(chicken);
System.out.println(roastFood.cook());
// 测试多重修饰的食物
SteamedFood steamedFood = new SteamedFood(roastFood);
System.out.println(steamedFood.cook());
}
// 输出:
// 鸡肉
// 烤鸡肉
// 蒸烤鸡肉
评价一下,装饰类主要是需要定义一个通用的抽象方法或者接口,供实体对象和装饰对象继承,并通过装饰类修饰该对象。因为通过修饰类对外暴露的cook()方法和原对象一致(肯定是一致的,因为他们重写同一个方法),所以这个装饰类对象就可以当做源对象使用,不同的是对源对象做了一层装饰。
所以我们在“多重修饰”中可以看到,我们把装饰后的对象roastFood,直接当做实物对象使用,完全没有任何问题,虽然它本质上和实物对象不同,但是使用效果确是一致的(这个和我们平时开发一样,将一个对象作为自己的成员类变量,然后对外暴露的方法,其实就是把该成员类变量的方法包一层,道理是一样的)。
所以回过头来,我们再看FactoryBean,其实它应该也有一个成员类变量,我们通过Bean初始化FactoryBean时,就可以通过FactoryBean对这个Bean进行装饰。
优点
缺点
欢迎大家多多点赞,更多文章,请关注微信公众号“楼仔进阶之路”,点关注,不迷路~~