设计模式:装饰模式

一、概述

装饰模式(Decorator Pattern)是一种结构型设计模式,它允许在不改变对象接口的前提下向对象添加新的行为。通过使用装饰模式,我们可以动态地将责任附加到对象上,而无需修改代码中的其他类。

二、使用场景

  1. 需要扩展一个类的功能,或给一个类添加附加职责。
  2. 动态地为一个对象添加功能,这些功能可以随时撤销。
  3. 通过一种方式将类的核心职责和装饰功能区分开来,以便简化代码和减少重复代码。

三、结构

装饰模式主要包含以下几个部分:

  1. 组件接口(Component):定义了要动态添加功能的对象的接口。
  2. 具体组件(ConcreteComponent):实现了组件接口的类。
  3. 装饰类(Decorator):持有一个组件对象的引用,并实现组件接口,通过这种方式,装饰类可以在调用具体组件的方法前后添加新的行为。
  4. 具体装饰类(ConcreteDecorator):继承装饰类,并具体实现装饰功能。

四、代码实现

下面是一个Java实现装饰模式的例子,展示了如何给一个简单的文本消息添加多种装饰(如加密和压缩)。

// Component 接口
interface Message {
    String getContent();
}

// 具体组件
class TextMessage implements Message {
    private String content;

    public TextMessage(String content) {
        this.content = content;
    }

    @Override
    public String getContent() {
        return content;
    }
}

// 装饰类
abstract class MessageDecorator implements Message {
    protected Message message;

    public MessageDecorator(Message message) {
        this.message = message;
    }

    @Override
    public String getContent() {
        return message.getContent();
    }
}

// 具体装饰类 A
class EncryptedMessage extends MessageDecorator {

    public EncryptedMessage(Message message) {
        super(message);
    }

    @Override
    public String getContent() {
        return encrypt(message.getContent());
    }

    private String encrypt(String content) {
        // 简单的加密逻辑
        return new StringBuilder(content).reverse().toString();
    }
}

// 具体装饰类 B
class CompressedMessage extends MessageDecorator {

    public CompressedMessage(Message message) {
        super(message);
    }

    @Override
    public String getContent() {
        return compress(message.getContent());
    }

    private String compress(String content) {
        // 简单的压缩逻辑
        return content.substring(0, 5); // 仅为示例
    }
}

// 客户端代码
public class DecoratorPatternDemo {
    public static void main(String[] args) {
        Message message = new TextMessage("Hello, World!");

        // 加密消息
        Message encryptedMessage = new EncryptedMessage(message);
        System.out.println("Encrypted: " + encryptedMessage.getContent());

        // 压缩消息
        Message compressedMessage = new CompressedMessage(message);
        System.out.println("Compressed: " + compressedMessage.getContent());

        // 先加密再压缩
        Message encryptedCompressedMessage = new CompressedMessage(new EncryptedMessage(message));
        System.out.println("Encrypted & Compressed: " + encryptedCompressedMessage.getContent());
    }
}

五、装饰模式在JDK中的运用

1. java.io 包中的类

java.io 包中的类是装饰模式的经典实现之一。特别是 InputStreamOutputStreamReaderWriter 等类,这些类的装饰器实现方式使得可以动态地向基本流添加功能。

示例代码:

import java.io.*;

public class DecoratorPatternInJDK {
    public static void main(String[] args) {
        try {
            InputStream fileStream = new FileInputStream("example.txt");
            InputStream bufferedStream = new BufferedInputStream(fileStream);
            InputStream gzipStream = new GZIPInputStream(bufferedStream);

            int data;
            while ((data = gzipStream.read()) != -1) {
                System.out.print((char) data);
            }
            
            gzipStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,FileInputStream 是一个基本的输入流,BufferedInputStreamGZIPInputStream 是装饰器类,它们为输入流添加了缓冲和解压缩的功能。

2. java.util 包中的 Collections

Collections 类提供了一些静态方法来返回集合的包装器,这些包装器为集合添加了同步(线程安全)和不可变的特性。

示例代码:

import java.util.*;

public class CollectionsDecoratorExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("One");
        list.add("Two");
        list.add("Three");

        List<String> synchronizedList = Collections.synchronizedList(list);
        List<String> unmodifiableList = Collections.unmodifiableList(list);

        // 输出原始列表
        System.out.println("Original List: " + list);
        
        // 输出同步列表
        System.out.println("Synchronized List: " + synchronizedList);
        
        // 输出不可修改列表
        System.out.println("Unmodifiable List: " + unmodifiableList);
        
        // 尝试修改不可修改列表将引发 UnsupportedOperationException
        try {
            unmodifiableList.add("Four");
        } catch (UnsupportedOperationException e) {
            System.out.println("Cannot modify unmodifiable list");
        }
    }
}

在这个例子中,synchronizedListunmodifiableList 是对原始列表的装饰器,为其添加了同步和不可变的特性。

六、结论

装饰模式通过将附加功能包装在装饰类中,使得我们可以灵活地扩展对象的功能,而不需要修改对象的核心代码。这种模式在需要扩展类的功能时特别有用,特别是当扩展功能是可以动态组合和变化的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值