首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【详解】JAVA设计模式装饰模式(Decorator)

【详解】JAVA设计模式装饰模式(Decorator)

原创
作者头像
大盘鸡拌面
发布2025-12-09 10:25:05
发布2025-12-09 10:25:05
2820
举报

JAVA设计模式装饰模式(Decorator)

在软件工程中,设计模式是解决特定问题的通用可重用解决方案。装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。装饰模式可以在不修改原对象的情况下动态地添加功能,这使得它成为一种非常灵活的设计模式。

装饰模式的基本原理

装饰模式的核心思想是将类的功能进行扩展,而不需要改变原有类的结构和代码。这种模式通过创建一个包装对象(即装饰器)来包裹真实的对象,并在需要的时候增加额外的功能。装饰器类实现了与被装饰对象相同的接口,因此可以替代被装饰的对象使用。

装饰模式的主要角色
  1. 抽象组件(Component):定义了一个对象接口,可以给这些对象动态地添加职责。
  2. 具体组件(Concrete Component):定义了一个具体的对象,也可以给这个对象添加一些职责。
  3. 装饰器(Decorator):持有一个组件对象的实例,并定义了一个与抽象组件接口一致的接口。
  4. 具体装饰器(Concrete Decorator):负责向组件添加新职责。

实现装饰模式

下面通过一个简单的例子来说明如何在Java中实现装饰模式。假设我们有一个​​Beverage​​(饮料)类,它可以被不同的调料装饰,如牛奶、糖等。

定义抽象组件
代码语言:javascript
复制
public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}
具体组件
代码语言:javascript
复制
public class Espresso extends Beverage {
    public Espresso() {
        description = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}
抽象装饰器
代码语言:javascript
复制
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

具体装饰器

代码语言:javascript
复制
public class Mocha extends CondimentDecorator {
    Beverage beverage;

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

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

    @Override
    public double cost() {
        return .20 + beverage.cost();
    }
}
使用装饰模式
代码语言:javascript
复制
public class StarbuzzCoffee {
    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

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

在这个例子中,​​Espresso​​是一个具体的组件,而​​Mocha​​是一个具体的装饰器。通过装饰器,我们可以轻松地给​​Espresso​​添加额外的调料,同时保持原有的接口不变。

装饰模式是一种结构型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。下面是一个简单的Java示例,展示了如何使用装饰模式来扩展功能。

实际应用场景

假设我们有一个文本消息系统,基本的功能是发送纯文本消息。但是,随着需求的发展,我们需要添加一些额外的功能,比如加粗、斜体等格式化选项。使用装饰模式可以在不修改原有代码的情况下动态地添加这些功能。

示例代码
  1. 定义接口或抽象类

首先,定义一个基础的消息接口或抽象类:

代码语言:javascript
复制
public interface Message {
    String getContent();
}
  1. 实现基础消息类

然后,创建一个实现了 ​​Message​​ 接口的基础消息类:

代码语言:javascript
复制
public class PlainTextMessage implements Message {
    private String content;

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

    @Override
    public String getContent() {
        return content;
    }
}
  1. 定义装饰器基类

接下来,定义一个装饰器基类,它也实现了 ​​Message​​ 接口,并持有一个 ​​Message​​ 对象的引用:

代码语言:javascript
复制
public abstract class MessageDecorator implements Message {
    protected Message message;

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

    @Override
    public String getContent() {
        return message.getContent();
    }
}
  1. 创建具体的装饰器

现在,我们可以创建具体的装饰器来添加特定的行为,例如加粗和斜体:

代码语言:javascript
复制
public class BoldDecorator extends MessageDecorator {
    public BoldDecorator(Message message) {
        super(message);
    }

    @Override
    public String getContent() {
        return "<b>" + super.getContent() + "</b>";
    }
}

public class ItalicDecorator extends MessageDecorator {
    public ItalicDecorator(Message message) {
        super(message);
    }

    @Override
    public String getContent() {
        return "<i>" + super.getContent() + "</i>";
    }
}
  1. 使用装饰器

最后,我们可以在客户端代码中使用这些装饰器来动态地添加功能:

代码语言:javascript
复制
public class Client {
    public static void main(String[] args) {
        // 创建一个基础的消息
        Message plainMessage = new PlainTextMessage("Hello, World!");

        // 使用装饰器添加功能
        Message boldMessage = new BoldDecorator(plainMessage);
        Message italicBoldMessage = new ItalicDecorator(boldMessage);

        // 输出结果
        System.out.println(plainMessage.getContent()); // Hello, World!
        System.out.println(boldMessage.getContent()); // <b>Hello, World!</b>
        System.out.println(italicBoldMessage.getContent()); // <i><b>Hello, World!</b></i>
    }
}

运行结果

运行上述代码,输出将会是:

代码语言:javascript
复制
Hello, World!
<b>Hello, World!</b>
<i><b>Hello, World!</b></i>

装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。装饰模式的核心思想是动态地给一个对象添加一些额外的职责,而不是通过继承的方式。这种方式比静态继承更灵活,因为它可以在运行时选择性地添加或删除功能。

下面是一个简单的Java实现装饰模式的例子:

1. 定义接口或抽象类

首先,定义一个接口或抽象类,这个接口或抽象类描述了基本的行为。

代码语言:javascript
复制
public interface Coffee {
    String getDescription();
    double getCost();
}
2. 创建具体组件

接下来,创建具体的组件类,这些类实现了上述接口或继承了抽象类。

代码语言:javascript
复制
public class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

    @Override
    public double getCost() {
        return 10.0;
    }
}
3. 创建装饰器基类

然后,创建一个装饰器基类,该类也实现了相同的接口或继承了相同的抽象类,并持有一个具体组件的引用。

代码语言:javascript
复制
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee decoratedCoffee) {
        this.decoratedCoffee = decoratedCoffee;
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }

    @Override
    public double getCost() {
        return decoratedCoffee.getCost();
    }
}
4. 创建具体装饰器

最后,创建具体的装饰器类,这些类扩展了装饰器基类并添加了新的功能。

代码语言:javascript
复制
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee decoratedCoffee) {
        super(decoratedCoffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", with Milk";
    }

    @Override
    public double getCost() {
        return super.getCost() + 2.0;
    }
}

public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee decoratedCoffee) {
        super(decoratedCoffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", with Sugar";
    }

    @Override
    public double getCost() {
        return super.getCost() + 1.0;
    }
}
5. 使用装饰器

现在,你可以使用这些装饰器来动态地给咖啡添加不同的配料。

代码语言:javascript
复制
public class DecoratorPatternDemo {
    public static void main(String[] args) {
        Coffee simpleCoffee = new SimpleCoffee();
        System.out.println(simpleCoffee.getDescription() + " Cost: " + simpleCoffee.getCost());

        Coffee milkCoffee = new MilkDecorator(simpleCoffee);
        System.out.println(milkCoffee.getDescription() + " Cost: " + milkCoffee.getCost());

        Coffee sugarMilkCoffee = new SugarDecorator(milkCoffee);
        System.out.println(sugarMilkCoffee.getDescription() + " Cost: " + sugarMilkCoffee.getCost());
    }
}
输出结果
代码语言:javascript
复制
Simple Coffee Cost: 10.0
Simple Coffee, with Milk Cost: 12.0
Simple Coffee, with Milk, with Sugar Cost: 13.0

在这个例子中,​​SimpleCoffee​​ 是一个具体的组件,而 ​​MilkDecorator​​ 和 ​​SugarDecorator​​ 是具体的装饰器。通过将 ​​SimpleCoffee​​ 对象传递给装饰器,我们可以在不改变原始对象的情况下为其添加新的功能。这种方式非常灵活,可以在运行时根据需要动态地组合不同的装饰器。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JAVA设计模式装饰模式(Decorator)
    • 装饰模式的主要角色
    • 实现装饰模式
      • 定义抽象组件
      • 具体组件
      • 抽象装饰器
      • 使用装饰模式
      • 实际应用场景
      • 示例代码
      • 1. 定义接口或抽象类
      • 2. 创建具体组件
      • 3. 创建装饰器基类
      • 4. 创建具体装饰器
      • 5. 使用装饰器
      • 输出结果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档