前言:上周面试,被问JavaI/O流的时候面试官说BufferrdReader使用了装饰模式,那么来谈一谈你对装饰模式的理解吧,结果我直接哑火了。之后赶紧来学一下,并写下这篇文章。
装饰模式简介
装饰模式是一种结构型设计模式,用于替代继承,不需要给要扩展的类写子类也能增加其功能,动态地给一个对象增加额外的职责,是一种比继承更灵活的方案。
装饰模式的角色:抽象构件Component、具体构件ConcreteComponent、抽象装饰类Decorator、具体装饰类ConcreteDecorator,简单的类图如下:
Java实现
下面给一个Java实现的例子:
abstract class Component{
abstract public String getDesc();
}
class ConcreteComponent extends Component{
public String getDesc() {
return "equipment : rookie equipment";
}
}
class Decorator extends Component{
protected Component component;
Decorator(Component component){
this.component=component;
}
public String getDesc(){
return component.getDesc();
}
}
class Decorator_glasses extends Decorator{
Decorator_glasses(Component component) {
super(component);
}
@Override
public String getDesc() {
return super.getDesc()+", cool dark glasses";
}
}
class Decorator_mask extends Decorator{
Decorator_mask(Component component) {
super(component);
}
@Override
public String getDesc() {
return super.getDesc()+", mystic mask";
}
}
这里提供两个装饰类,能给角色提供墨镜和面具,而角色初始只拥有新手装备,下面测试一下装饰有没有起作用。
public static void main(String[] args){
Component hero = new ConcreteComponent();
hero = new Decorator_mask(hero);
hero = new Decorator_glasses(hero);
System.out.println(hero.getDesc());
}
执行结果:
总结
装饰模式的应用场景:1.想要给对象动态、透明地添加职责;2.如果系统里的对象使用继承,或者使用继承不利于系统的维护时,我们使用装饰模式给对象添加职责。
优点:1.扩展功能时比继承更加灵活,不会导致类的数量大量增加;2.可以多次给一个对象装饰;3.可以动态地装饰对象,装饰是可选的,还可以通过排列组合创造出很多种装饰的方式;4.装饰类之间是独立的,互不干扰,符合开闭原则。
缺点:1.使用装饰模式时在系统内会产生较多的对象,占用更多的系统资源;2.比起继承,装饰模式的实现更复杂,在开发时可能会出现错误,调试时也更加困难,对于被多次装饰的组件要逐次排查。