首页 > 其他分享 >设计模式-装饰器模式

设计模式-装饰器模式

时间:2023-09-12 14:04:50浏览次数:47  
标签:Coffee coffee 模式 装饰 public 设计模式 class

装饰器模式


(文章目录)


什么是装饰器模式

  装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。


为什么使用装饰器模式

使用装饰者模式有如下好处:   1. 避免了类爆炸问题,简化了设计   2. 易于扩展,可以灵活组合不同调料   3. 装饰类和被装饰类可以独立变化,没有严格耦合   4. 符合开闭原则,扩展开放(可以添加更多调料),修改关闭(原有类不需要修改) 我们举个例子来说明,假设我们要开发一个咖啡店点餐系统。我们有以下对象:

  • Coffee:咖啡类,价格5元
  • Milk:牛奶类,价格1元
  • ChocolateChip:巧克力豆类,价格2元
  • WhipCream:奶油类,价格2元

如果不使用装饰者模式,我们可以这样设计:

// 咖啡类
public class Coffee {
    private String description = "咖啡";
    private double price = 5;
}

// 牛奶咖啡
public class CoffeeWithMilk extends Coffee {
    public CoffeeWithMilk() {
        description += " + 牛奶";
        price += 1; 
    }
}

// 巧克力豆咖啡
public class CoffeeWithChocolateChip extends Coffee {
   // ...
} 

// 奶油咖啡
public class CoffeeWithWhipCream extends Coffee {
   // ... 
}

// 巧克力豆牛奶咖啡
public class CoffeeWithMilkAndChocolateChip extends CoffeeWithMilk {
   // ...    
} 

但是这种设计有几个缺点:

  1. 会产生很多子类,导致过度继承,设计变得复杂
  2. 如果想添加更多的调料组合,子类数量会急剧增加,不易于维护
  3. Coffee 类和子类是耦合的,一旦 Coffee 类变化,子类也需要变化

使用装饰者模式可以这样设计:

java
public interface Coffee {  
    public double getPrice(); 
}

public class SimpleCoffee implements Coffee {
    @Override
    public double getPrice() {
        return 5; 
    }
}

public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

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

    @Override
    public double getPrice() {
        return coffee.getPrice();
    }
}

public class Milk extends CoffeeDecorator {
    public Milk(Coffee coffee) {
        super(coffee); 
    }

    @Override
    public double getPrice() {
        return super.getPrice() + 1; 
    }
}

// 其他调料装饰类(ChocolateChip,WhipCream)定义类似...

Coffee c = new SimpleCoffee();
c = new Milk(c); // 牛奶
c = new ChocolateChip(c);// 牛奶巧克力豆
c = new WhipCream(c);// 牛奶巧克力豆

System.out.println(c.getPrice()); // 9


如何使用装饰器模式

从上面的代码中,我们可以看出,装饰器模式主要包含以下角色。

  1、抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。   2、具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。   3、抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。   4、具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

在这里插入图片描述 上面的代码示例中,我们将各个类进行下划分:

  • Coffee 接口属于抽象构件
  • SimpleCoffee 类属于具体构件
  • CoffeeDecorator 抽象类属于抽象装饰
  • Milk、ChocolateChip 等类属于具体装饰

总结

  装饰器模式不是简单的“用组合替代继承”,装饰器模式相对于简单的组合关系,还有两个比较特殊的地方。

  • 装饰器类和原始类继承同样的父类,这样我们可以对原始类“嵌套”多个装饰器类。
  • 装饰器类是对功能的增强,这也是装饰器模式应用场景的一个重要特点。

标签:Coffee,coffee,模式,装饰,public,设计模式,class
From: https://blog.51cto.com/u_15322552/7445027

相关文章

  • Android开发中常见的设计模式
    Android开发中常见的设计模式对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次。而在android开发中,必要的了解一些设计模式又是非常有必要的。对于想系统的学习设计模式的同学,这里推荐2本书。一本是HeadFirst系列的HeadH......
  • Padavan配置白名单模式及上网时间控制
    登录Padavan管理后台,高级设置--->防火墙--->mac访问控制--->mac访问控制模式【允许模式---仅列表中的设备可获取网络;拒绝模式---列表中的设备拒绝访问网络】,禁止访问路由器主机这项一定打开,不然试了下没效果,开了就是未在列表中的设备不能访问路由器,初次连接的设备也无法获取ip地......
  • 在.NET中实现事件驱动编程模式
    当在.NET中实现事件驱动编程模式时,你可以创建自定义事件和委托,然后让对象触发事件,以便其他对象可以订阅并响应这些事件。这种模式常用于构建可扩展和松散耦合的应用程序。以下是一个基本示例,演示如何在C#中实现事件驱动编程。步骤1:创建一个C#控制台应用程序首先,创建一个新的C#控......
  • Ubuntu Server 22.04 双网卡绑定 配置文件 Bond mode 1 : active-backup 主备模式
    UbuntuServer22.041.拓扑视图实例 2.备份配置文件修改前备份root@ax:~#cpetc/netplan/00-installer-config.yamletc/netplan/00-installer-config.yaml.orig修改配置文件,Ubuntu严格区分格式,空格缩进。简要说明:eno1-eno4,关闭dhcp;bond0只绑定eno1、eno2,实际可根据情况,绑定更多......
  • 软件设计模式系列之三———工厂方法模式
    1模式的定义工厂方法模式是一种常见的设计模式,属于创建型设计模式之一,它在软件工程中用于对象的创建。该模式的主要思想是将对象的创建过程抽象化,将具体对象的实例化延迟到子类中完成,以便在不同情况下可以创建不同类型的对象,而客户端代码不需要知道实际创建的对象类型。2举例......
  • "快速编辑模式"带来的命令行程序暂停问题
    在Windows下,"快速编辑模式"(QuickEditMode)允许用户通过点击和拖动来选择命令提示符窗口中的文本。但是,这可能会导致某些命令行程序暂停,直到用户按下Enter键。因此,某些用户可能希望禁用这个模式。要禁用"快速编辑模式",请按照以下步骤操作:打开命令提示符(cmd)。右......
  • 【23种设计模式】装饰模式(九)
    前言装饰模式,英文名称:DecoratorPattern。我第一次看到这个名称想到的是另外一个词语“装修”,我就说说我对“装修”的理解吧,大家一定要看清楚,是“装修”,不是“装饰”。在房子装修的过程中,各种功能可以相互组合,来增加房子的功用。类似的,如果我们在软件系统中,要给某个类型或者对象......
  • 装饰器2
    装饰器装饰器的简易版本importtimedefindex():time.sleep(3)print('fromindex')defhome():print('fromhome')deffunc():print('fromfunc')defouter(func_name):#func_name=index......
  • 【设计模式】观察者模式Observer:消息的订阅-发布
    (目录)观察者模式是一种非常流行的设计模式,也常被叫作订阅-发布模式。观察者模式在现代的软件开发中应用非常广泛,比如,商品系统、物流系统、监控系统、运营数据分析系统等。常说的基于事件驱动的架构,其实也是观察者模式的一种最佳实践。当观察某一个对象时,对象传递出的每一个行......
  • 5.前端设计模式之容器/展现模式
    Enforceseparationofconcernsbyseparatingtheviewfromtheapplicationlogic通过将视图层和应用逻辑分离实现关注点分离 这个有点像Java应用开发中经常看到的MVC架构模式,实现数据、业务逻辑和展示层分离。这个模式在React中需要两个组件实现:容器组件主要负责获取数据,获取......