前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >23种设计模式,装饰器模式实战

23种设计模式,装饰器模式实战

原创
作者头像
小马哥学JAVA
发布2024-04-06 12:52:15
1490
发布2024-04-06 12:52:15

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

概念

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

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

优点

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

缺点

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

Java代码示例

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

首先,定义组件接口:

java复制代码

代码语言:javascript
复制
public interface Beverage {
    String getDescription();
    double cost();
}

具体组件实现:

java复制代码

代码语言:javascript
复制
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复制代码

代码语言:javascript
复制
public abstract class CondimentDecorator implements Beverage {
    protected Beverage beverage;
    public abstract String getDescription();
}

具体装饰实现:

java复制代码

代码语言:javascript
复制
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复制代码

代码语言:javascript
复制
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());
    }
}

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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概念
  • 优点
  • 缺点
  • Java代码示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档