介绍
在不改变原有对象的基础上增加新功能,可以动态的给对象增加功能
优点
- 继承的补充,比继承更灵活。
- 多个装饰类的排列组合可以产生不同效果
- 符合开闭原则
缺点
- 增加了更多的类和代码
- 在动态装饰、多层装饰时更复杂
装饰者模式和代理模式
装饰者关注给对象动态增加方法,对象一般持有的是老对象,代理是控制对象的访问,对象一般是新建出来的。
装饰者模式和适配器模式
都可以叫包装模式,适配器和被适配的类具有不同的接口
代码
抽象被装饰对象
public abstract class ANoodles {
public abstract String getDesc();
public abstract int getPrice();
}
具体被装饰对象
public class Noodles extends ANoodles {
@Override
public String getDesc() {
return "白面条:6 ";
}
@Override
public int getPrice() {
return 6;
}
}
抽象装饰者基础类
public abstract class AbstractDecorator extends ANoodles {
ANoodles noodles;
public AbstractDecorator(ANoodles noodles) {
this.noodles = noodles;
}
@Override
public String getDesc() {
return this.noodles.getDesc();
}
@Override
public int getPrice() {
return this.noodles.getPrice();
}
}
具体装饰者——鸡蛋
public class EggDecorator extends AbstractDecorator {
public EggDecorator(ANoodles noodles) {
super(noodles);
}
@Override
public String getDesc() {
return super.getDesc()+"加个鸡蛋 2 ";
}
@Override
public int getPrice() {
return super.getPrice()+2;
}
}
具体装饰者——肉
public class MeetDecorator extends AbstractDecorator {
public MeetDecorator(ANoodles noodles) {
super(noodles);
}
@Override
public String getDesc() {
return super.getDesc()+"加一块肉 5 ";
}
@Override
public int getPrice() {
return super.getPrice()+5;
}
}
测试类
public class Test {
public static void main(String[] args) {
ANoodles noodles = new Noodles();
noodles = new EggDecorator(noodles);
noodles = new MeetDecorator(noodles);
System.out.println(noodles.getDesc());//白面条:6 加个鸡蛋 2 加一块肉 5
System.out.println(noodles.getPrice());//13
}
}
装饰者的核心在于:
被装饰者和具体的装饰者都继承自同一个抽象类,因此两者之间的联系可以使用同一个父抽象类进行关联。
由抽象父类持有具体的被装饰者类,并通过构造器注入到不同的装饰者中。
装饰者在编译时通过自身继承的抽象父类提供的接口进行方法增强,运行时会有实际的被装饰者注入进来,从而实现和具体的被装饰者类的解耦。