Java 装饰器模式(Decorator)

装饰器模式

  装饰器模式属于结构型设计模式。它允许向一个现有的对象添加新的功能,同时又不改变其结构。

  例如:给一个普通的杯子加上杯盖、杯套,让它具有保温防烫等功能,而杯子本身的基本结构并没有发生变化。在软件开发过程中,当我们需要在运行时动态的为对象添加职责,并且避免通过继承来扩展功能带来的类层次结构复杂问题时,装饰器模式就派上用场了。

  装饰器模式主要包含以下几个角色:

  1.抽象组件(component):定义一个抽象接口,规范具体组件和装饰器的行为

  2.具体组件(concrete component):实现抽象组件接口,是被装饰的具体对象

  3.抽象装饰器(decorator):继承或实现抽象组件接口,持有一个抽象组件的引用,并定义一个可以动态添加职责的方法

  4.具体装饰器(concrete decorator):实现抽象装饰器接口,负责为具体组件添加具体功能

核心思想

  1.动态扩展:在运行时添加/删除功能,而非编译时

  2.组合优于继承:通过对象组合实现功能叠加,避免类爆炸

  3.透明性:装饰后的对象与原对象接口一致,对客户端透明

典型使用场景

  1.I/O流操作(Java原生)如InputStream、BufferedInputStream、DataInputStream等,都是典型的装饰器模式应用
  2.权限控制/日志记录等通用功能增强,在不改变核心业务逻辑的前提下,为服务添加日志、缓存、安全等功能。

  3.UI组件扩展,比如按钮组件加上边框、阴影、滚动等效果

  4.Spring的AOP(面向切面编程)Spring使用了类似装饰器的思想来实现方法拦截和增强。

image

 

装饰器模式实现步骤

1.故事背景:机器人功能扩展的两种方案

在智能家居领域,某科技公司推出了第一代家用机器人,它具备三个核心功能:对话、唱歌和播放音乐。

image

// 第一代机器人:基础功能
interface Robot {
    void talk();    // 对话
    void sing();    // 唱歌
    void playMusic(); // 播放音乐
}
 
class FirstGenerationRobot implements Robot {
    @Override
    public void talk() {
        System.out.println("机器人:你好,我能陪你聊天");
    }
 
    @Override
    public void sing() {
        System.out.println("机器人:正在播放《青花瓷》");
    }
 
    @Override
    public void playMusic() {
        System.out.println("机器人:正在播放轻音乐");
    }
}

 

 随着用户需求升级,厂家希望扩展机器人的功能,让它能够扫地和跳舞。针对这个需求,有两种技术方案可供选择:

image

 

⑴.方案一:传统继承(厂家升级方案)

  厂家选择开发第二代机器人,通过继承第一代产品并添加新功能:

    接口定义
// 基础接口:第一代机器人支持的功能
interface Robot {
    void talk();
    void sing();
    void playMusic();
}

 

 
  类实现
// 第一代机器人(基础实现)
class FirstGenerationRobot implements Robot {
    @Override
    public void talk() {
        System.out.println("对话中...");
    }
 
    @Override
    public void sing() {
        System.out.println("正在唱歌...");
    }
 
    @Override
    public void playMusic() {
        System.out.println("播放音乐中...");
    }
}
 
// 第二代机器人:通过继承方式扩展功能
class SecondGenerationRobot extends FirstGenerationRobot {
    public void sweep() {
        System.out.println("正在扫地...");
    }
 
    public void dance() {
        System.out.println("正在跳舞...");
    }
}

 

测试代码

public class InheritanceTest {
    public static void main(String[] args) {
        System.out.println("=== 继承方式测试 ===");
        SecondGenerationRobot robot = new SecondGenerationRobot();
        robot.talk();
        robot.sing();
        robot.playMusic();
        robot.sweep();  // 扩展功能
        robot.dance();   // 扩展功能
    }
}

⑵.方案二:装饰器模式

image

 

posted @ 2025-10-13 22:26  krt-wanyi  阅读(8)  评论(0)    收藏  举报