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日

相关文章

  • 详细介绍解决vue和jsp结合的方法

    下面是针对“详细介绍解决vue和jsp结合的方法”的完整攻略: 1. 确定Vue和JSP结合方式 在解决Vue和JSP结合的问题时,需要明确选择的结合方式。一般来说,可以通过以下方式将Vue和JSP结合: Vue.js作为静态资源引入JSP页面:将Vue.js代码编译打包后,引入到JSP页面中,通过Vue.js的实例化和调用,实现Vue的DOM操作和交互效果…

    Java 2023年6月15日
    00
  • Java File类的简单使用教程(创建、删除、遍历与判断是否存在等)

    Java File类的简单使用教程 Java中的File类是用于操作文件和目录的类,可以进行文件和目录的创建、删除、遍历以及判断文件和目录是否存在等操作。下面我们将介绍如何使用File类进行这些操作。 创建文件 要创建一个文件,我们可以使用File类的构造函数,然后使用createNewFile()方法。示例代码如下: File file = new Fil…

    Java 2023年5月19日
    00
  • java使用UDP实现点对点通信

    下面是我为您提供的“java使用UDP实现点对点通信”的攻略。 一、什么是UDP UDP是无连接的传输协议,数据报(Datagram)套接字就是基于UDP协议实现的,它不会像TCP那样保证数据传输的可靠性,传输的数据包也不要求应答。但是,UDP具备比TCP更快的传输速度和更小的网络开销,因此,当需要高效传输数据时,可以选择UDP协议。 二、使用UDP实现点对…

    Java 2023年5月20日
    00
  • Java如何实现可折叠Panel方法示例

    下面是Java如何实现可折叠Panel方法的详细攻略。 什么是可折叠Panel 可折叠Panel指的是一个面板,可以通过单击它的折叠按钮或者拖动它的边缘来展开或折叠。在界面设计中,使用可折叠Panel可以使用户界面更加灵活、紧凑和易于使用。 实现可折叠Panel的方法 要实现一个可折叠Panel,首先需要继承JPanel类,然后添加一个折叠按钮和折叠功能。 …

    Java 2023年5月26日
    00
  • 浅谈jsp中的9个隐含对象

    接下来我将为大家详细讲解“浅谈JSP中的9个隐含对象”的完整攻略。 1. JSP的9个隐含对象 在JSP页面中,有9个隐含对象,他们分别是: request:表示客户端发来的请求,被封装成了request对象,在JSP页面中可以通过request对象访问请求中的参数信息。 response:表示服务器对请求做出的响应,被封装成了response对象,在JSP…

    Java 2023年6月15日
    00
  • JVM Tomcat性能实战(推荐)

    下面是针对“JVM Tomcat性能实战(推荐)”的完整攻略: 1. 了解JVM和Tomcat 在开始优化之前,需要了解JVM和Tomcat的基本知识。JVM是Java虚拟机,用于运行Java代码。Tomcat是一个流行的Web应用程序服务器,常用于运行Java Web应用程序。 2. 性能测试 在进行优化之前,需要先进行性能测试。可以使用各种工具进行测试,…

    Java 2023年5月20日
    00
  • Java虚拟机最多支持多少个线程的探讨

    Java虚拟机最多支持多少个线程的探讨 Java虚拟机(JVM)是一种能够在不同操作系统上运行Java程序的虚拟机,它的主要功能是将Java字节码转换为计算机可执行代码。在Java程序中,线程(Thread)是用来实现多任务处理的最基本单元,线程的数量对于程序执行的效率和性能有着至关重要的作用。 JVM的线程数量上限 JVM的线程并发数量并不是无限的,它受到…

    Java 2023年5月19日
    00
  • java读写ini文件、FileOutputStream问题

    要在Java中读写ini文件,有以下几个步骤: 引入ini4j库 ini4j是一个开源的Java类库,主要用于解析INI文件。 在Maven项目中,可以在pom.xml文件中添加以下依赖: <dependency> <groupId>org.ini4j</groupId> <artifactId>ini4j&l…

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