装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
当我们想要扩展一个类,又由于继承类过多,工作量大,耦合度过高等原因纠结的时候,装饰器模式无疑是最好的选择。这种模式做到了装饰类和被装饰类相互独立发展,装饰类可以动态的添加功能,相比于维护庞大的功能不同的被装饰类类来说更灵活。这里举个简单的例子:
一个表演家Actor抽象类,具有表演的能力。
public abstract class Actor {
/**
* 表演
*/
public abstract void act();
}
三个子类,舞蹈家DanceActor,演员MovieActor,歌唱家SingActor继承了表演家Actor:
public class DanceActor extends Actor {
@Override
public void act() {
System.out.println("跳舞");
}
}
public class MovieActor extends Actor {
@Override
public void act() {
System.out.println("演电影");
}
}
public class SingActor extends Actor {
@Override
public void act() {
System.out.println("唱歌");
}
}
现在我们要让演员和歌唱家具有发声的功能,如果不适用装饰者模式,我们需要在这两个字类中实现这个功能,由于是两个子类,这样实现看起来没有问题,但是如果大量的子类需要具有相同的功能,这种方法就比较难以接受。接下来我们使用装饰器模式来实现。首先定义一个装饰类基类:
public class FilterActorDetorator extends Actor{
protected volatile Actor actor;
public FilterActorDetorator(Actor actor) {
this.actor = actor;
}
@Override
public void act() {
actor.act();
}
}
这个基类维护了Actor的变量,并实现了Actor相同的方法,这样子类装饰器在使用时并不会感受到什么差异。接下来我们构建一个子装饰类:
public class VoiceActorDetorator extends FilterActorDetorator {
public VoiceActorDetorator(Actor actor) {
super(actor);
}
public void getVoice(){
if(actor instanceof SingActor || actor instanceof MovieActor){
System.out.println("发声");
}else{
throw new RuntimeException("不具备该功能");
}
}
}
子装饰类VoiceActorDetorator添加了发声的功能,但是需要注意的是:并不是所有的子类都具备该功能,所以在使用时需要注意,这也是装饰器模式的弊端:
public class DecoratorMain {
public static void main(String[] args) {
SingActor singActor = new SingActor();
DanceActor danceActor = new DanceActor();
VoiceActorDetorator voiceActorDetorator = new VoiceActorDetorator(singActor);
VoiceActorDetorator voiceActorDetorator1 = new VoiceActorDetorator(danceActor);
voiceActorDetorator.act();
voiceActorDetorator1.act();
voiceActorDetorator.getVoice();
voiceActorDetorator1.getVoice();
}
}
控制台:
Exception in thread "main" java.lang.RuntimeException: 不具备该功能
at com.designmodel.decorator.VoiceActorDetorator.getVoice(VoiceActorDetorator.java:21)
at com.designmodel.decorator.DecoratorMain.main(DecoratorMain.java:20)
唱歌
跳舞
发声
装饰器模式的优缺点都很明显,优点是灵活,解耦;缺点是复杂。下图是这个装饰器模式的结构:
来源:CSDN
作者:JAVA探索
链接:https://blog.csdn.net/top_explore/article/details/103584718