Head First Design Patterns - 装饰者模式

装饰者模式允许在不修改原有类的情况下动态添加功能,通过继承和共享基类实现。它避免了大量拓展类导致的类爆炸问题,遵循开闭原则,如JavaI/O流中的应用
摘要由CSDN通过智能技术生成

什么是装饰者模式

装饰者模式动态地将额外责任附加到对象上。对于拓展功能,装饰者提供子类化的弹性替代方案。 --《Head First Design Patterns》中的定义

为什么会有装饰者模式

根据上述定义,简单来说,装饰者模式就是对原有的类,增加一些额外的功能或者行为。用普通的继承或者组合也可以实现,但是单纯用继承或者组合来做,会产生大量的拓展类而导致"类爆炸"。

书中用咖啡的价格为例,说明了类爆炸这个概念:

咖啡店的咖啡的种类有4种,每种的价格不一样
在这里插入图片描述

若除了咖啡本身,还可以要求加上不同的调料,例如蒸奶(milk)、豆奶(soy)、摩卡(Mocha)。这样子,子类的拓展组合,就会有很多种,从而导致类爆炸,如下图所示。
在这里插入图片描述

装饰者模式的特点

  • 装饰者和被装饰者继承同一个基类。因为装饰者必须能够取代被装饰者,这里利用继承达到“类型匹配”,而不是利用继承获取“行为”
  • 装饰者拥有(has a)一个与被装饰者相同的基类类型属性(类似策略模式)
  • 可以用一个或多个装饰者类包装同一个对象
  • 装饰者可以在所委托被装饰者的行为之前或行为之后或行为之前与之后加上自己的行为,以达到特定的目的

装饰者模式的类图

在这里插入图片描述

例子

以上述咖啡店的咖啡价格为例子

  1. 基类:对应上图中的Component
public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

2. 咖啡种类的拓展类: 对应上图中的ConcreteComponent

public class Espresso extends Beverage{
    public Espresso() {
        description = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}

public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "HouseBlend";
    }

    @Override
    public double cost() {
        return .89;
    }
}

装饰器

public abstract class CondimentDecorator extends Beverage{
    Beverage beverage;

    @Override
    public abstract String getDescription();
}

4. 调料类

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 beverage.cost() + .20;
    }
}

public class Whip extends CondimentDecorator{
    public Whip(Beverage beverage) {
        this.beverage = beverage;
    }

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

    @Override
    public double cost() {
        return beverage.cost() + .10;
    }
}

5. 测试

public static void main(String[] args) {
        // 要一杯浓缩咖啡,不加调料
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        //要一杯HouseLand,带有2份mocha和whip
        Beverage beverage1 = new HouseBlend();
        beverage1 = new Mocha(beverage1);
        beverage1 = new Mocha(beverage1);
        beverage1 = new Whip(beverage1);

        System.out.println(beverage1.getDescription() + " $" + beverage1.cost());
    }

上述的咖啡喝调料可以在不改动基类代码的基础上,进行随意组合。

装饰者模式用到的设计原则

类应该对拓展开放,对修改关闭(开闭原则)

应用

java中的I/O流
在这里插入图片描述
参考:装饰者模式

### 回答1: 《Head First设计模式-深入浅出设计模式》是一本以简单有趣的方式介绍设计模式的书籍。设计模式是在软件开发中解决特定问题的一种经验总结,它们提供了在实际开发中可重用、可靠、灵活的解决方案。 该书的主要特点是通过生动有趣的讲解和丰富多样的图表、示例来帮助读者更好地理解和应用设计模式。作者采用了大量的图形和实例来解释设计模式的概念,使读者能够迅速理解并应用这些概念。 这本书涵盖了23种常用的设计模式,如工厂模式、单例模式、适配器模式、装饰器模式等。每一种设计模式都以一个实际的例子开始,引出该模式解决的问题,然后详细解释其结构和应用,最后通过示例代码展示如何使用该模式。 此外,该书还介绍了设计模式之间的关系和如何选择合适的设计模式。它教授了读者如何在具体问题中识别出适用的设计模式,并提供了一些实际的应用建议。 《Head First设计模式-深入浅出设计模式》以其独特的教学风格和简洁明了的讲解深受读者喜爱。这本书不仅适合初学者了解设计模式,也适合有一定经验的开发人员进一步提高他们的软件设计和编程能力。 总之,这本书以其生动有趣的讲解方式和大量的图表、实例为读者介绍了设计模式的基本概念和具体应用,是学习和理解设计模式的一本不可或缺的指南。 ### 回答2: 《Head First设计模式:深入浅出设计模式》是一本主要介绍软件设计模式的书籍。设计模式是在软件开发中经常出现的问题的解决方案,可以帮助开发人员更好地构建可重用、可扩展、可维护的代码。 这本书以深入浅出的方式介绍了23种常见的设计模式,通过生动有趣的讲解和大量的图形和实例,使读者能够更加轻松地理解和掌握设计模式。它采用了非传统的学习方式,通过讲故事、练习、谜题等方式将设计模式的概念和使用方法娓娓道来。 该书首先从简单的设计模式开始,引导读者逐步理解和掌握基础的设计原则和模式,如单例模式、工厂模式等。然后,逐渐深入介绍更复杂的模式,如装饰器模式、观察者模式、策略模式等。每个模式都通过具体的案例和代码示例进行讲解,帮助读者理解模式的思想和应用场景。 除了具体的设计模式之外,这本书还关注了如何将设计模式应用到现实的软件开发中。它探讨了如何根据不同的需求选择合适的设计模式,以及如何通过设计模式提高代码的质量和可维护性。 总的来说,《Head First设计模式:深入浅出设计模式》是一本非常有趣、易懂且实用的设计模式入门书籍。无论是初学者还是有一定经验的开发人员,都能从中获得有益的知识和经验,提高软件开发的能力和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值