Java设计模式之装饰者模式详解和代码实例

Java设计模式之装饰者模式详解和代码实例

什么是装饰者模式?

装饰者模式是一种结构型设计模式,以动态的方式将责任附加到对象上。装饰者提供了与继承相比更为灵活的替代方案,以扩展功能。

装饰者模式的组成

  • 抽象构件(Component):定义装饰者和被装饰者的公共接口。
  • 具体构件(ConcreteComponent):这是被装饰者,这是需要进行功能扩展的对象。
  • 装饰者(Decorator):这是包含被装饰者的实例,装饰者将在被装饰者的行为前面或后面添加一些自己的行为。
  • 具体装饰者(ConcreteDecorator):这个组件通过添加自己的行为来扩展与具体构件(ConcreteComponent)相关联的对象的功能。

装饰者模式的优缺点

优点

  • 可以动态的扩展一个对象的功能,而继承无法实现这一点。
  • 可以使用多个具体装饰者封装具体构件类形成复合装饰者,从而实现各种不同的装饰效果。
  • 装饰者模式符合开闭原则,可以在不修改原有代码的基础上,增加功能或修改装饰器的行为。

缺点

  • 使用装饰者模式会产生许多小对象,在一定程序上会增加系统的复杂性和理解难度。
  • 装饰者模式会改变对象之间的关系,增加对象的嵌套深度,加重了程序的运行负载,可能会导致性能问题。

装饰者模式的代码实例

下面是一个简单的装饰者模式的实例。

示例一:咖啡店

我们来看一个咖啡店的例子,想要给咖啡加上牛奶、糖、摩卡等等,同时也可能会有不加任何调料的咖啡。

// 抽象构件
interface Beverage {
    int cost();// 获取饮料价格
    String getDescription();// 获取饮料描述
}
// 具体构件
class Coffee implements Beverage {
    private int cost = 10;
    @Override
    public int cost() {
        return cost;
    }
    @Override
    public String getDescription() {
        return "纯咖啡";
    }
}
// 装饰器
class AddonDecorator implements Beverage {
    private Beverage beverage;
    AddonDecorator(Beverage beverage) {
        this.beverage = beverage;
    }
    @Override
    public int cost() {
        return this.beverage.cost();
    }
    @Override
    public String getDescription() {
        return this.beverage.getDescription();
    }
}
// 具体装饰器
class Sugar extends AddonDecorator {
    Sugar(Beverage beverage) {
        super(beverage);
    }
    @Override
    public int cost() {
        return super.cost() + 2;
    }
    @Override
    public String getDescription() {
        return super.getDescription() + " 加糖";
    }
}
class Milk extends AddonDecorator {
    Milk(Beverage beverage) {
        super(beverage);
    }
    @Override
    public int cost() {
        return super.cost() + 3;
    }
    @Override
    public String getDescription() {
        return super.getDescription() + " 加牛奶";
    }
}
// 测试类
public class TestDecorator {
    public static void main(String[] args) {
        // 纯咖啡
        Beverage beverage = new Coffee();
        System.out.println("纯咖啡价格:" + beverage.cost() + ", 描述:" + beverage.getDescription());

        // 加糖咖啡
        beverage = new Sugar(beverage);
        System.out.println("加糖咖啡价格:" + beverage.cost() + ", 描述:" + beverage.getDescription());

        // 加牛奶咖啡
        beverage = new Milk(beverage);
        System.out.println("加牛奶咖啡价格:" + beverage.cost() + ", 描述:" + beverage.getDescription());

        // 加糖加牛奶咖啡
        beverage = new Milk(new Sugar(new Coffee()));
        System.out.println("加糖加牛奶咖啡价格:" + beverage.cost() + ", 描述:" + beverage.getDescription());
    }
}

在上面的例子中,Beverage 是抽象构件,Coffee 是具体构件,AddonDecorator 是装饰器,SugarMilk都是具体装饰器。

示例二:文件读写

下面是一个文件读写的例子。我们要为文件读写增加加密、压缩等其他操作。

// 文件操作接口,抽象构件
interface FileOperation {
    void write(String text);
    String read();
}
// 具体文件操作类,也是具体构件
class TextFile implements FileOperation {
    private String fileName;
    TextFile(String fileName) {
        this.fileName = fileName;
    }
    @Override
    public void write(String text) {
        System.out.println("Write to " + fileName + ": " + text);
    }
    @Override
    public String read() {
        return "Text from " + fileName;
    }
}
// 文件操作装饰器
class FileDecorator implements FileOperation {
    private FileOperation file;
    FileDecorator(FileOperation file) {
        this.file = file;
    }
    @Override
    public void write(String text) {
        file.write(text);
    }
    @Override
    public String read() {
        return file.read();
    }
}
// 具体文件加密装饰器
class EncryptedFileDecorator extends FileDecorator {
    EncryptedFileDecorator(FileOperation file) {
        super(file);
    }
    @Override
    public void write(String text) {
        text = text + " [encrypted]";
        super.write(text);
    }
    @Override
    public String read() {
        String text = super.read();
        return text.replace("[encrypted]", "");
    }
}
// 具体文件压缩装饰器
class CompressedFileDecorator extends FileDecorator {
    CompressedFileDecorator(FileOperation file) {
        super(file);
    }
    @Override
    public void write(String text) {
        text = text + " [compressed]";
        super.write(text);
    }
    @Override
    public String read() {
        String text = super.read();
        return text.replace("[compressed]", "");
    }
}
// 测试类
public class TestFileDecorator {
    public static void main(String[] args) {
        //不加任何操作
        FileOperation file = new TextFile("test.txt");
        file.write("Hello World");
        System.out.println("Read from file: " + file.read());

        //加密操作
        file = new EncryptedFileDecorator(file);
        file.write("Hello World");
        System.out.println("Read from file: " + file.read());

        //压缩操作
        file = new CompressedFileDecorator(file);
        file.write("Hello World");
        System.out.println("Read from file: " + file.read());

        //加密和压缩操作
        file = new CompressedFileDecorator(new EncryptedFileDecorator(new TextFile("test.txt")));
        file.write("Hello World");
        System.out.println("Read from file: " + file.read());
    }
}

在上面的例子中,FileOperation 是抽象构件,TextFile 是具体构件,FileDecorator是装饰器,EncryptedFileDecoratorCompressedFileDecorator是具体装饰器。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之装饰者模式详解和代码实例 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • JavaWeb实现邮件发送接收功能

    作为网站作者,如果您需要为您的网站实现邮件发送和接收功能,可以使用JavaWeb技术来实现。以下是JavaWeb实现邮件发送和接收功能的完整攻略。 1. 设置邮件服务器 在JavaWeb中实现邮件发送和接收功能,首先需要设置SMTP服务器和POP3服务器信息。SMTP服务器用于发送邮件,POP3服务器用于接收邮件。 在JavaWeb中设置SMTP服务器信息和…

    Java 2023年5月23日
    00
  • sublime text 3 快捷键大全以及配置编译环境

    Sublime Text 3 快捷键大全以及配置编译环境 Sublime Text 3 是一款功能强大的文本编辑器,可以帮助开发者提高工作效率。在本文中,我们将讲解 Sublime Text 3 的快捷键大全以及如何配置编译环境。 Sublime Text 3 快捷键大全 Sublime Text 3 支持各种快捷键操作,以下是一些常用快捷键列表。 快捷键 …

    Java 2023年5月26日
    00
  • Spring Cloud Gateway编码实现任意地址跳转的示例

    首先我们来介绍一下Spring Cloud Gateway。 Spring Cloud Gateway是Spring Cloud生态中的一个全新项目,它是基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,旨在为微服务提供一种简单而统一的方式来访问外部服务。 那么,如何实现Spring Cloud Gat…

    Java 2023年5月20日
    00
  • java组件SmartUpload和FileUpload实现文件上传功能

    下面是“java组件SmartUpload和FileUpload实现文件上传功能”的完整攻略。 背景介绍 在Web开发中,文件上传是一个非常普遍的需求。文件上传可以用来上传用户头像、上传附件等,而Java作为一种广泛应用于Web开发的语言,也提供了不少关于文件上传的解决方案。本攻略将详细介绍使用Java组件SmartUpload和FileUpload实现文件…

    Java 2023年6月15日
    00
  • 什么是volatile关键字?

    什么是volatile关键字? volatile是C语言关键字之一,用于修饰变量。 通常情况下,当一个变量被定义后,系统在运行时会在内存中为其分配一块地址,该变量被存储在该内存地址中。当程序运行时会从该地址中读取该变量的值,不过在实际的程序中,可能会遇到一些特殊情况,这些特殊情况可能会导致该变量的值不再在该内存地址中,而是在其他位置上,这个时候就可以通过vo…

    Java 2023年5月10日
    00
  • jsp网页计数器实现示例

    下面是“JSP网页计数器实现示例”的完整攻略,该攻略包括以下步骤: 1. 在JSP页面中添加计数器代码 要在JSP页面中添加计数器,需要先在页面的头部导入计数器的Java类,然后在页面中使用JSP脚本将计数器的初始化以及计数器在页面上的输出实现。 示例代码: <%@ page import="com.example.Counter"…

    Java 2023年6月15日
    00
  • List集合多线程并发条件下不安全如何解决

    List集合在多线程并发条件下存在线程安全问题,主要是由于多个线程在同时对List进行增删改操作,会产生竞争条件。在此情况下,如果不进行处理,会导致List集合数据不一致或者抛出ConcurrentModificationException异常等问题。下面是解决List集合多线程并发不安全的完整攻略: 方案1:使用线程安全的List集合 Java提供了多个线…

    Java 2023年5月26日
    00
  • 浅谈Java8新特性Predicate接口

    浅谈Java8新特性Predicate接口 Java 8中新增加了Predicate接口,它定义了一个输入参数和返回值都为Boolean的函数。这个接口定义了许多实用的方法,可以被用来组合复杂的布尔逻辑。 Predicate接口定义 Predicate接口有一个test方法,返回一个Boolean类型,其定义如下: @FunctionalInterface …

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部