简介
装饰者模式可以动态的给一些对象增加责任。在扩展功能的问题上,装饰者比类的继承更有弹性。
在设计的时候,给一个对象的功能进行一些修饰,对功能进行扩展和增强
特点
a)相比于继承,灵活性更大
b)类的继承会产生很多类,但是使用装饰者模式,会产生很多中间对象。
应用
a)给一个对象动态的添加职能,不影响其他对象。
b)动态添加的职能可以被取消
场景模拟
有一个歌手,会唱歌,但是他同时也是一个演员,会演戏,但这人有才,又是一个主持人,会主持节目,如果名望很大,说不定还能被某个学校请去做客座教授,当教师。
但很多歌手可能不像上面那位,那么有才,有的除了唱歌可能会演戏,也可能会主持,这样就会有多重情况。
如果我们要模拟上面的全部情况,可能就需要创建:
歌手、
歌手+演员 、歌手+主持人 、 歌手+教师、
歌手+演员+主持人、歌手+主持人+教师、歌手+演员+教师、
歌手+演员+主持人+教师
一共8个类。
如果我们采用装饰模式,当用歌手+演员装饰出A后,再需要装饰出歌手+演员+主持人B的时候,可以直接在A的基础上装饰出B。
在继承机制中,sing()方法运行会产生什么结果,是提前就定好的。
如果我们可以将这个sing()方法变为动态的,即运行时才确定的行为,然后在修饰的时候,加上相应的修饰就可以了。
那这里的动态就是动态绑定,一个类要动态绑定某个对象的行为,只需要持有这个对象的引用,然后在运行的时候,根据这个引用绑定到具体的对象,这样就可以体现出不同的行为。
代码示例
歌手类
public class Singer {
public void sing(){
System.out.println("我会唱歌。。。");
}
}
歌手修饰类
public class DecorateSinger extends Singer{
private Singer singer;
public DecorateSinger(Singer singer){
this.singer = singer;
}
public void sing() {
singer.sing();
}
}
演员类
public class Actor extends DecorateSinger{
public Actor(Singer singer) {
super(singer);
}
public void sing(){
act();
super.sing();
}
public void act(){
System.out.println("我会演戏。。。");
}
}
主持人类
public class Presenter extends DecorateSinger{
public Presenter(Singer singer) {
super(singer);
}
public void sing(){
present();
super.sing();
}
public void present(){
System.out.println("我会主持。。。");
}
}
教师类
public class Teacher extends DecorateSinger{
public Teacher(Singer singer) {
super(singer);
}
public void sing(){
teach();
super.sing();
}
public void teach(){
System.out.println("我会教书。。。");
}
}