1.产生背景
假如一个杂技戏团之前非常的火爆,观众络绎不绝。但是随着花样的不变通,观众慢慢的也就看厌了。于是马戏团老板琢磨着,怎么才能给观众带来新鲜感的同时,减少成本呢?或许可以给杂技演员装饰装饰。
我们可以新加一个部门,这个部门就负责给那些表演杂技的演员换上一些奇特,新颖的服装,再教他们几个新的杂技,让观众换换口味。
- 装饰模式:当一个对象已经对外提供核心功能,但是在某些情况下又无法完全满足用户需要的时候,通常情况下我们可以通过修改原来的代码从而满足新的需求。但是这种方式其实违背了设计模式原则中的开放-封闭原则,影响了原有代码的稳定性,并且降低了代码的内聚程度。这种情况下,装饰模式便可派上用场。
2.概念
- 装饰模式(Decorator Pattern)是一个向现有对象动态新增功能的同时,不改变原有的结构的模式。
- 原理:在用户与被装饰者之间引入一个中介类,该中介类对用户假装为被装饰者,在实现中通过调用被装饰者,并在装饰者前后添加附加功能,相较于继承会更加的灵活
- 目的:在不修改现有对象(代码)的情况下,给该对象增加更多的职责和功能(如:数据预处理)。
3.类图
4.代码
public abstract class Component {
public abstract void operation();
}
public class ConcreteComponent extends Component{
@Override
public void operation() {
System.out.println("I can tell jokes");
}
}
public abstract class Decorator extends Component {
protected Component component;
public void setComponent(Component component) {
this.component = component;
}
}
@Override
public void operation() {
if(component != null) {
component.operation();
}
}
}
public class FlyDecorator extends Decorator {
private static String behavior = "I can fly";
public void operation() {
this.component.operation();
System.out.print(behavior);
}
public class SwimDecorator extends Decorator {
private static String behavior = "I can swim";
public void operation() {
this.component.operation();
System.out.print(behavior);
}
}
public class MainClass {
public static void main(String[] args) {
Decorator decorator = new FlyDecorator();
decorator.setComponent(new ConcreteComponent());
decorator.operation();
}
}
运行结果:
这里可以发现,我们原本的被装饰者只会一项技能:“讲笑话”。但是经过我们的装饰,用户发现,被装饰者不仅会讲笑话逗观众开心,还会飞在空中了呢
5.优缺点
- 优点
装饰模式和继承的目的都是扩展对象的功能,但是装饰器模式相比于继承会更加的灵活,通过实现不同的具体装饰类以及具体装饰类之间的排列组合,便可创建出更多不同行为的组合。并且新增功能职责不需要更改现有代码,实现高内聚 - 缺点
通常来说,更高的灵活性往往意味着更高的复杂度。如果系统过度使用,会使程序变的很复杂。