设计模式(三)装饰者模式

129 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

装饰者模式是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。装饰者模式动态地将责任附加到对象身上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案,比生成子类更加灵活。

通常在继承关系中,为了扩展功能需要新增子类进行扩展,而装饰者模式,可以在不扩展子类的情况下,将对象的功能进行动态的扩展。

装饰者模式类图如下:

图片

  • 抽象构件(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");
    }
}

现在有一个场景,每天下班我们都会收拾书包把东西装入书包中,例如电脑,杯子,耳机,书等,一个人每天放入的顺序都不同,所以这是不断变化的,那我们就用装饰者模式来完成这种场景。

图片

Packpublic 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,通过测试类,我们可以看到,客户端可以随意进行功能的添加,由客户端进行动态的执行放入的顺序,每个人放入的顺序不同,通过装饰者模式可以进行不同的组装来完成需求的变更。

装饰模式允许系统动态决定增加一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。通过使用不同的具体装饰类以及这些装饰类的排列组合,就可以创造出很多不同行为的组合。