23种设计模式,装饰器模式的概念优缺点以及JAVA代码举例

简介: 【4月更文挑战第5天】装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式作为现有类的一个包装。

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式作为现有类的一个包装。

概念

装饰器模式涉及四个角色:

  • 组件(Component):定义一个对象接口,可以给这些对象动态地添加职责。
  • 具体组件(Concrete Component):定义了一个具体的对象,也可以给这个对象添加一些职责。
  • 装饰(Decorator):持有一个组件(Component)对象的实例,并定义了与组件接口一致的接口。
  • 具体装饰(Concrete Decorator):负责给组件添加额外的职责。

优点

  1. 增加对象的职责:装饰器模式提供了一种灵活的替代方案来扩展对象的功能,比继承更加灵活。
  2. 动态地添加功能:装饰器模式允许用户动态地给一个对象添加额外的职责。添加的职责也容易撤销。
  3. 扩展系统功能:可以使用多个不同的装饰器对同一个对象进行装饰,实现不同的效果。

缺点

  1. 会导致系统产生很多小对象:每个装饰器都是一个对象,过多使用装饰器会造成程序中小对象的数量大增。
  2. 复杂性增加:装饰器模式会增加系统的复杂性,多层装饰比较复杂。
  3. 维护困难:大量使用装饰器,维护时需要特别注意装饰链的配置,可能会引起错乱。

Java代码示例

考虑一个简单的咖啡店系统,咖啡是一种饮料,顾客可以选择添加不同的调料(如牛奶、摩卡、豆浆等)。

首先,定义组件接口:

java复制代码

public interface Beverage {
    String getDescription();
    double cost();
}

具体组件实现:

java复制代码

public class Espresso implements Beverage {
    @Override
    public String getDescription() {
        return "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}

public class HouseBlend implements Beverage {
    @Override
    public String getDescription() {
        return "House Blend Coffee";
    }

    @Override
    public double cost() {
        return 0.89;
    }
}

装饰器实现:

java复制代码

public abstract class CondimentDecorator implements Beverage {
    protected Beverage beverage;
    public abstract String getDescription();
}

具体装饰实现:

java复制代码

public class Mocha extends CondimentDecorator {
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    @Override
    public double cost() {
        return .20 + beverage.cost();
    }
}

public class Soy extends CondimentDecorator {
    public Soy(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Soy";
    }

    @Override
    public double cost() {
        return .15 + beverage.cost();
    }
}

使用示例:

java复制代码

public class DecoratorPatternDemo {
    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        Beverage beverage2 = new HouseBlend();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Soy(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
    }
}

在这个例子中,Espresso和HouseBlend是具体的饮料,Mocha和Soy是装饰者,它们通过包装一个Beverage对象并在其基础上添加额外的功能(即调料)来工作。

相关文章
|
11月前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
715 6
|
11月前
|
Java 数据处理 API
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
448 115
|
11月前
|
安全 Java 编译器
为什么你的Java代码需要泛型?类型安全的艺术
为什么你的Java代码需要泛型?类型安全的艺术
345 98
|
11月前
|
Java 编译器 API
java最新版和java8的区别,用代码展示
java最新版和java8的区别,用代码展示
759 43
|
11月前
|
设计模式 消息中间件 安全
【JUC】(3)常见的设计模式概念分析与多把锁使用场景!!理解线程状态转换条件!带你深入JUC!!文章全程笔记干货!!
JUC专栏第三篇,带你继续深入JUC! 本篇文章涵盖内容:保护性暂停、生产者与消费者、Park&unPark、线程转换条件、多把锁情况分析、可重入锁、顺序控制 笔记共享!!文章全程干货!
530 1
|
11月前
|
Java 编译器 Go
【Java】(5)方法的概念、方法的调用、方法重载、构造方法的创建
Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建,在其他地方被引用方法的优点使程序变得更简短而清晰。有利于程序维护。可以提高程序开发的效率。提高了代码的重用性。方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。这种就属于驼峰写法下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。
428 4
|
11月前
|
安全 Java 容器
告别空指针噩梦:Optional让Java代码更优雅
告别空指针噩梦:Optional让Java代码更优雅
593 94
|
11月前
|
安全 Java 容器
告别繁琐判空:Optional让你的Java代码更优雅
告别繁琐判空:Optional让你的Java代码更优雅
|
12月前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
1394 3
|
12月前
|
安全 Java 应用服务中间件
Spring Boot + Java 21:内存减少 60%,启动速度提高 30% — 零代码
通过调整三个JVM和Spring Boot配置开关,无需重写代码即可显著优化Java应用性能:内存减少60%,启动速度提升30%。适用于所有在JVM上运行API的生产团队,低成本实现高效能。
1300 3

热门文章

最新文章