装饰者模式是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。装饰者模式动态地将责任附加到对象身上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案,比生成子类更加灵活。
通常在继承关系中,为了扩展功能需要新增子类进行扩展,而装饰者模式,可以在不扩展子类的情况下,将对象的功能进行动态的扩展。
装饰者模式类图如下:
抽象构件(Component):给出一个抽象接口,以规范接收附加功能。的对象。
具体构件(ConcerteComponent):定义一个将要接收附加功能的类。装饰者(Decorator):持有一个构件对象的实例,并定义一个与构件接口一致的接口。
具体装饰者(ConcretDecoratorA,ConcretDecoratorB):负责给构件对象添加附加的功能。
抽象构件Component
public abstract class Component {
public abstract void operation();
}
具体构件(ConcreteComponent)
public class ConcerteComponent extends Component {
@Override
public void operation() {
System.out.println(0);
}
}
装饰(Decorator)
public abstract class Decorator extends Component {
private Component component;
public void setComponent(Component component){
this.component=component;
}
@Override
public void operation() {
if (component!=null){
component.operation();
}
}
}
具体装饰ConcretDecoratorA
public class ConcretDecoratorA extends Decorator {
@Override
public void operation() {
super.operation();
System.out.println("1");
}
}
具体装饰ConcretDecoratorB
public class ConcretDecoratorB extends Decorator {
@Override
public void operation() {
super.operation();
System.out.println("2");
}
}
现在有一个场景,每天下班我们都会收拾书包把东西装入书包中,例如电脑,杯子,耳机,书等,一个人每天放入的顺序都不同,所以这是不断变化的,那我们就用装饰者模式来完成这种场景。
Pack类
public abstract class Pack {
public abstract void toPack();
}
ConcertPack
public class ConcertPack extends Pack {
@Override
public void toPack() {
System.out.println("打开书包");
}
}
Decorator
public class Decorator extends Pack {
Pack pack;
public void setPack(Pack pack) {
this.pack = pack;
}
@Override
public void toPack() {
if (pack != null) {
pack.toPack();
}
}
}
ComputerPack
public class ComputerPack extends Decorator {
@Override
public void toPack() {
super.toPack();
System.out.println("将电脑放入书包");
}
}
BookPack
public class BookPack extends Decorator {
@Override
public void toPack() {
super.toPack();
System.out.println("将书放入书包");
}
}
CupPack
public class CupPack extends Decorator {
@Override
public void toPack() {
super.toPack();
System.out.println("将杯子放入书包");
}
}
HeadsetPack
public class HeadsetPack extends Decorator {
@Override
public void toPack() {
super.toPack();
System.out.println("将耳机放入书包");
}
}
测试类
public class PackTest {
public static void main(String[] args) {
ConcertPack concertPack=new ConcertPack();
CupPack cupPack=new CupPack();
ComputerPack computerPack=new ComputerPack();
BookPack bookPack=new BookPack();
HeadsetPack headsetPack=new HeadsetPack();
cupPack.setPack(concertPack);
computerPack.setPack(cupPack);
bookPack.setPack(computerPack);
headsetPack.setPack(bookPack);
headsetPack.toPack();
}
}
打开书包
将杯子放入书包
将电脑放入书包
将书放入书包
将耳机放入书包
Process finished with exit code 0
这个例子当中Pack就相当于抽象构件,而具体构件就是ConcertPack,装饰者是Decorate,具体装饰者就是要放入书包的这些东西继承Decorate,通过测试类,我们可以看到,客户端可以随意进行功能的添加,由客户端进行动态的执行放入的顺序,每个人放入的顺序不同,通过装饰者模式可以进行不同的组装来完成需求的变更。
装饰模式允许系统动态决定增加一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。通过使用不同的具体装饰类以及这些装饰类的排列组合,就可以创造出很多不同行为的组合。
扫码关注
有趣的灵魂在等你