装饰器模式

  • Post author:
  • Post category:其他


装饰器模式又称包装模式,是一种结构型模式。这种设计模式是指能够在一个类的基础上增加一个装饰类(也可以叫包装类),并在装饰类中增加一些新的特性和功能。这样,通过对原有类的包装,就可以在不改变原有类的情况下为原有类增加更多的功能。

Phone接口,它规定了发送和接收语音的抽象方法。

public interface Phone {
    
    String callIn();
    
    Boolean callOut(String info);
    
}

然后定义一个类 TelePhone,实现 Phone 接口,能够实现打电话的功能

public class TelePhone implements Phone {

    @Override
    public String callIn() {
        System.out.println("接收语音·······");
        return "get info";
    }

    @Override
    public Boolean callOut(String info) {
        System.out.println("发送语音:" + info);
        return true;
    }
}

现在要创建一个装饰类,在不改变原有 TelePhone 的基础上,实现通话录音功能。

public class PhoneMessageDecorator implements Phone {

    private Phone decoratedPhone;

    public PhoneMessageDecorator(Phone decoratedPhone) {
        this.decoratedPhone = decoratedPhone;
    }

    @Override
    public String callIn() {
        System.out.println("启动录音······");
        String info = decoratedPhone.callIn();
        System.out.println("结束录音,并保存录音文件");
        return info;
    }

    @Override
    public Boolean callOut(String info) {
        System.out.println("启动录音······");
        Boolean result = decoratedPhone.callOut(info);
        System.out.println("结束录音,并保存录音文件");
        return result;
    }

    public String receiveMessage() {
        System.out.println("接收······");
        return "phone message";
    }

    public Boolean sendMessage(String info) {
        System.out.println("发送消息:" + info);
        return true;
    }
}

这样,经过 PhoneRecordDecorator包装过的 Phone就具有了通话录音功能。

public class DecoratorMainTest {

    public static void main(String[] args) {
        System.out.println("原来没有录音功能");
        Phone phone = new TelePhone();
        phone.callOut("Hello girl !");

        System.out.println("\n\n");

        System.out.println("经过装饰后的phone有录音功能==");
        Phone phoneWithRecorder = new PhoneRecordDecorator(phone);
        phoneWithRecorder.callOut("Hello girl !");
    }
}

程序运行结果:

原来没有录音功能
发送语音:Hello girl !



经过装饰后的phone有录音功能==
启动录音······
发送语音:Hello girl !
结束录音,并保存录音文件

我们使用装饰器模式对被包装类的功能进行了扩展,但是不影响原有类。遵照这个思想,还可以通过装饰类增加新的方法、属性等。

我们给原来的 TelePhone类增加收发短信功能

package com.happyghost.javapattern.decorator;

public class PhoneMessageDecorator implements Phone {

    private Phone decoratedPhone;

    public PhoneMessageDecorator(Phone decoratedPhone) {
        this.decoratedPhone = decoratedPhone;
    }

    @Override
    public String callIn() {
        System.out.println("启动录音······");
        String info = decoratedPhone.callIn();
        System.out.println("结束录音,并保存录音文件");
        return info;
    }

    @Override
    public Boolean callOut(String info) {
        System.out.println("启动录音······");
        Boolean result = decoratedPhone.callOut(info);
        System.out.println("结束录音,并保存录音文件");
        return result;
    }

    public String receiveMessage() {
        System.out.println("接收······");
        return "phone message";
    }

    public Boolean sendMessage(String info) {
        System.out.println("发送消息:" + info);
        return true;
    }
}

通过测试

public class DecoratorMainTest {

    public static void main(String[] args) { 

        //测试发送短信功能

        System.out.println("\n\n");

        System.out.println("测试发送短信功能==");
        Phone phoneMessage = new PhoneMessageDecorator(phone);
        ((PhoneMessageDecorator) phoneMessage).sendMessage("1111");
    }
}

程序运行结果:

测试发送短信功能==
发送消息:1111

装饰器模式在编程开发中经常使用。通常的使用场景是在一个核心基本类的基础上,提供大量的装饰类,从而使核心基本类经过不同的装饰类修饰后获得不同的功能。装饰类还有一个优点,就是可以叠加使用,即一个核心基本类可以被多个装饰类修饰,从而同时具有多个装饰类的功能。



版权声明:本文为zhangjm123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。