Java设计模式——装饰者模式

Java设计模式——装饰者模式

1.简介

'装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许用户通过在一个对象上动态地添加职责或行为来增强其功能。这种类型的设计模式属于对象结构型模式,在不需要改变一个对象的内部结构的条件下,给对象动态地增加一些额外的职责。装饰者模式相比生成子类更为灵活。

2.核心组成

装饰者模式主要包含以下四种角色:

  1. 抽象组件(Component):定义一个对象的接口,可以给这些对象动态地添加职责。
  2. 具体组件(ConcreteComponent):实现或继承抽象组件,并添加基础的行为或属性。
  3. 装饰者(Decorator):持有一个抽象组件的引用,并定义一个与抽象组件一致的接口。
  4. 具体装饰者(ConcreteDecorator):实现装饰者接口,并给具体组件对象添加额外的职责。

3.工作原理

装饰者模式的工作原理是动态地将责任附加到对象上。若要扩展一个类的功能,装饰者提供了一个比继承更有弹性的替代方案。

4.使用场景

  1. 动态地给一个对象添加功能:装饰者模式允许我们在运行时动态地给一个对象添加职责,而不是在编译时静态地定义。
  2. 扩展功能不改变接口:使用装饰者模式时,不需要修改现有类的接口,就可以在运行时动态地扩展类的功能。
  3. 透明地使用对象:装饰者模式中的装饰者对象和被装饰对象实现了相同的接口,所以客户端代码可以透明地使用它们,不需要知道它们到底是装饰者对象还是被装饰对象。

5.优缺点

优点

  1. 装饰者和被装饰对象有相同的超类,因此继承了装饰者模式中的装饰对象和被装饰对象的类型一致性的特点。
  2. 装饰者模式可以动态地扩展一个实现类的功能,且可以无限制地使用装饰模式。
  3. 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

缺点

  1. 多层装饰比较复杂。
  2. 装饰模式会导致设计中出现许多小类,如果过度使用会使程序变得很复杂。

6.Java的实现例子

我们将以Beverage(饮料)作为抽象组件,并有一个具体的Coffee(咖啡)实现。我们将为咖啡添加一些装饰者,如Milk(牛奶)和Sugar(糖)。

首先,定义Beverage接口和Coffee类:

// 抽象组件:Beverage  
public interface Beverage {  
    String getDescription();  
    double cost();  
}  
  
// 具体组件:Coffee  
public class Coffee implements Beverage {  
    @Override  
    public String getDescription() {  
        return "Coffee";  
    }  
  
    @Override  
    public double cost() {  
        return 2.0;  
    }  
}

接下来,定义Decorator类,它实现了Beverage接口并持有一个Beverage对象的引用:

// 装饰者:Decorator  
public abstract class Decorator implements Beverage {  
    protected Beverage beverage;  
  
    public Decorator(Beverage beverage) {  
        this.beverage = beverage;  
    }  
  
    @Override  
    public String getDescription() {  
        return beverage.getDescription();  
    }  
  
    @Override  
    public double cost() {  
        return beverage.cost();  
    }  
}

现在,定义具体的装饰者类,如MilkSugar

// 具体装饰者:Milk  
public class Milk extends Decorator {  
    public Milk(Beverage beverage) {  
        super(beverage);  
    }  
  
    @Override  
    public String getDescription() {  
        return beverage.getDescription() + ", Milk";  
    }  
  
    @Override  
    public double cost() {  
        return beverage.cost() + 0.5;  
    }  
}  
  
// 具体装饰者:Sugar  
public class Sugar extends Decorator {  
    public Sugar(Beverage beverage) {  
        super(beverage);  
    }  
  
    @Override  
    public String getDescription() {  
        return beverage.getDescription() + ", Sugar";  
    }  
  
    @Override  
    public double cost() {  
        return beverage.cost() + 0.3;  
    }  
}

最后,在主程序中使用装饰者:

public class BeverageTest {  
    public static void main(String[] args) {  
        Beverage beverage = new Coffee();  
        System.out.println(beverage.getDescription() + " $" + beverage.cost());  
  
        Beverage beverageWithMilk = new Milk(beverage);  
        System.out.println(beverageWithMilk.getDescription() + " $" + beverageWithMilk.cost());  
  
        Beverage beverageWithMilkAndSugar = new Sugar(beverageWithMilk);  
        System.out.println(beverageWithMilkAndSugar.getDescription() + " $" + beverageWithMilkAndSugar.cost());  
    }  
}
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值