要对类的功能进行增强,可以新建一个类继承这个类,这种方法可以解决问题,但如果增加的功能越来越多,那继承的层次就越来越深,造成继承冗余的问题
装饰者模式可以不用继承类而增强类的功能,原理是使用对象之间的关联关系取代类之间的继承关系
当然还可以使用代理模式来增强类的功能
1、装饰器和被装饰者的抽象类
2、被装饰者(继承自装饰器和被装饰者的抽象类)
3、装饰器的抽象
4、装饰器的具体实现
Component
//装饰器和被装饰者的抽象类
public abstract class Component {
//共有的抽象方法,也就是待装饰的方法
public abstract void show();
}
Door
//被装饰者,继承自被装饰者和装饰器的抽象类
public class Door extends Component {
/**
* 待装饰方法的具体实现
*/
@Override
public void show() {
System.out.println("大家好我是门");
}
}
ComponentDecorator
//装饰器的抽象
public abstract class ComponentDecorator extends Component {
//被装饰者的引用,可以操作被装饰者
private Component component;
//装饰者的构造器,用于初始化被装饰者对象
public ComponentDecorator(Component component) {
this.component = component;
}
/**
* 重写待装饰方法
*/
@Override
public void show() {
component.show(); //调用被装饰者的待装饰方法
}
}
LockDecorator
//装饰器的具体实现
public class LockDecorator extends ComponentDecorator {
/**
* 构造器
* @param component 被装饰者对象
*/
public LockDecorator(Component component) {
super(component);
}
/**
* 重写待装饰方法
*/
@Override
public void show() {
this.setLock(); //调用装饰方法
super.show(); //调用父类的待装饰方法,也就是被装饰者的待装饰方法
}
/**
* 装饰方法的实现
*/
public void setLock(){
System.out.println("为组件加锁");
}
}
EyeDecorator
//装饰器的具体实现
public class EyeDecorator extends ComponentDecorator {
/**
* 构造器
* @param component 被装饰者对象
*/
public EyeDecorator(Component component) {
super(component);
}
/**
* 重写待装饰方法
*/
@Override
public void show() {
this.setEye(); //调用装饰方法
super.show(); //调用父类的待装饰方法,也就是被装饰者的待装饰方法
}
/**
* 装饰方法的实现
*/
public void setEye(){
System.out.println("为组件加猫眼");
}
}
Customer(测试类)
public class Customer {
public static void main(String[] args) {
Component door, decorator1, decorator2;
door = new Door();
decorator1 = new LockDecorator(door); //装饰door对象
decorator1.show();
System.out.println("------------------我是严肃的分割线------------------");
decorator2 = new EyeDecorator(decorator1); //装饰decorator1对象
decorator2.show();
}
}
为组件加锁
大家好我是门
------------------我是严肃的分割线------------------
为组件加猫眼
为组件加锁
大家好我是门
1、需要为某个现有对象添加一个新功能时,可以考虑装饰者模式或代理模式
2、某个对象的功能经常发生变化或经常需要动态添加功能时
JDK中的InputStream就是经典的装饰者模式,有兴趣的小伙伴可以研究下源码