专栏首页程序员小灰漫画设计模式:什么是 “装饰器模式” ?

漫画设计模式:什么是 “装饰器模式” ?

————— 第二天 —————

————————————

装饰器模式都包含哪些核心角色呢?

1. Component接口

在我们上面的例子中,Component接口相当于汽车接口,所有的被包装类、包装类,都继承于这个接口。

2. ConcreteComponent类

ConcreteComponent类是被包装的实现类。在例子中,奔驰汽车、宝马汽车、特斯拉汽车都属于这个角色。

3. Decorator抽象类

所有的包装类,都继承自Decorator抽象类,而Decorator类又实现了Component接口,这么做是为了实现多层嵌套包装。

4. ConcreteDecorator类

具体的包装类,用于扩充被包装类的功能,比如例子中的自动驾驶功能、飞行功能扩展。

这四大核心角色的关系是怎样的呢?我们可以用装饰器模式的UML类图来表达:

首先是汽车接口,也就是Component这个角色,里面定义了run这个行为:

public interface Car {
    void run();
}

接下来是各种汽车的实现类,也就是ConcreteComponent角色,不同的汽车对于run行为有着不同的实现:

public class BenzCar implements Car{
    @Override
    public void run() {
        System.out.println("奔驰开车了!");
    }
}

public class BmwCar implements Car{
    @Override
    public void run() {
        System.out.println("宝马开车了!");
    }
}

public class TeslaCar implements Car{
    @Override
    public void run() {
        System.out.println("特斯拉开车了!");
    }
}

下面是装饰器的抽象类,也就是Decorator角色,这个角色包含了被装饰的成员对象:

public class CarDecorator implements Car {

    protected Car decoratedCar;

    public CarDecorator(Car decoratedCar){
        this.decoratedCar = decoratedCar;
    }

    public void run(){
        decoratedCar.run();
    }
}

或许有人会觉得奇怪,为什么装饰器类也要实现Car接口呢?这正是装饰器模式的灵活之处。

继承自Car接口,可以让每一个装饰器本身也可以被更外层的装饰器所包装,包装的方式就是把Car对象作为参数,传入到外层装饰器的构造函数当中。

接下来是具体的装饰器实现类,也就是ConcreteDecorator角色。这些装饰器同样实现了run的行为,一方面会调用被包装对象的run方法,一方面会进行某些扩展操作(比如自动驾驶、飞行):

public class AutoCarDecorator extends CarDecorator {

    public AutoCarDecorator(Car decoratedCar){
        super(decoratedCar);
    }

    @Override
    public void run(){
        decoratedCar.run();
        autoRun();
    }

    private void autoRun(){
        System.out.println("开启自动驾驶");
    }}

public class FlyCarDecorator extends CarDecorator {

    public FlyCarDecorator(Car decoratedCar){
        super(decoratedCar);
    }

    @Override
    public void run(){
        decoratedCar.run();
        fly();
    }

    private void fly(){
        System.out.println("开启飞行汽车模式");
    }

}

最后,是我们的客户端类。客户端类负责创建被包装对象和装饰者,并决定如何进行包装和执行:

public class Client {

    public static void main(String[] args) {
        Car benzCar = new BenzCar();
        Car bmwCar = new BmwCar();
        Car teslaCar = new TeslaCar();
        //创建自动驾驶的奔驰汽车
        CarDecorator autoBenzCar = new AutoCarDecorator(benzCar);
        //创建飞行的、自动驾驶的宝马汽车
        CarDecorator flyAutoBmwCar = new FlyCarDecorator(new AutoCarDecorator(bmwCar));

        benzCar.run();
        bmwCar.run();
        teslaCar.run();
        autoBenzCar.run();
        flyAutoBmwCar.run();
    }
}

以输入流为例,为了满足不同输入场景,JDK设计了多种多样的输入流,包括ByteArrayInputStream、FileInputStream等等。

这些输入流都继承自共同的抽象类:InputStream。

与此同时,为了给这些输入流带来功能上的扩展,JDK设计了一个装饰器类,FilterInputStream。该类继承自InputStream,并且“组合”了InputStream成员对象。

从FilterInputStream类派生出了许多装饰器子类,包括BufferedInputStream,DataInputStream等等,分别提供了输入流缓冲,以及从输入流读取Java基本数据类型等额外功能。

—————END—————

本文分享自微信公众号 - 程序员小灰(chengxuyuanxiaohui),作者:小灰

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-01-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 漫画设计模式:什么是 “装饰器模式” ?

    在我们上面的例子中,Component接口相当于汽车接口,所有的被包装类、包装类,都继承于这个接口。

    肉眼品世界
  • 漫画:什么是 “设计模式” ?

    这本书是软件研发领域重要的里程碑,合著此书的四位作者 Erich Gamma,Richard Helm,Ralph Johnson ,John Vlisside...

    小灰
  • 漫画设计模式:什么是 “职责链模式” ?

    有一天,公司新来的产品经理有一个新需求,但她不知道这个需求应该由谁来负责。于是,她首先找到了小A:

    小灰
  • 码仔漫画|重学设计模式之装饰者模式

    注意:以上代码块用中文编写类名、变量名是为了让大家更好的理解,在实战过程中记得替换成相对应的英文。

    陈宇明
  • 设计模式-装饰器模式

    现代人每个人基本都会有一部手机,有的有好几部,正常情况下买手机有很多套餐,比如裸机、裸机+贴膜、裸机+贴膜+手机壳等,但是不一定每个人在购买的时候都一定会贴膜,...

    逍遥壮士
  • 设计模式-装饰器模式

    现在有一个场景:煎饼果子,科技园上班族早上去买煎饼果子(Pancake),有的人要加鸡蛋 (Egg)、有的人加火腿 (Ham)、有的人加生菜 (Lettuce)...

    码哥字节
  • 设计模式之装饰器设计模式

    Java的IO流使用了一种装饰器设计模式。它将IO流分成底层节点流和上层处理流,其中节点流用于和底层的物流存储结点直接关联——不同的物流节点获取该结点流的方式可...

    二十三年蝉
  • 设计模式之 装饰器模式

    tanoak
  • 设计模式之装饰器模式

    在日常生活中,装饰器模式的场景更多是的打扮了,一个妹子,嫌弃自己的脸长得不够漂亮,想换张脸很困难,但是化化妆还是很容易的(当然了,化妆也分男女的,此处指的是女士...

    Edison.Ma
  • PHP设计模式——装饰器模式

    咖啡深受人们的喜爱。咖啡的香气、味道和能力增强足以开启人们美好的一天。这就难怪为什么星巴克和咖啡豆这样的咖啡店在生意上可以做得这么好。

    Lemon黄
  • 设计模式之装饰器模式

    Attach additional responsibilities to an object dynamically keeping the same int...

    beginor
  • 【php设计模式】装饰器模式

    装饰器模式,顾名思义,就是对已经存在的某些类进行装饰,以此来扩展一些功能。其结构图如下:

    码缘
  • Go 设计模式- 装饰器模式

    装饰器模式主要解决继承关系过于复杂的问题,通过组合来代替继承,给原始类添加增强功能,这也是判断装饰器的一个重要依据,除此之外,装饰器还有一个特点,可以对原始类嵌...

    王小明_HIT
  • 漫画:什么是 “代理模式” ?

    在上面的代码中,代理类和业务类继承了相同的接口,并且重写了添加/删除学生的方法。

    小灰
  • 漫画:什么是 “原型模式” ?

    假如有一天,小灰被外星人抓走了,外星人要拿小灰做实验,想了解小灰在吃得好、睡得好、玩得开心的场景下,与现实中小灰的生存状态有什么区别。

    小灰
  • 设计模式 | 装饰模式

    在不修改原有对象的基础上, 将功能附加到对象上。符合我们软件开发的开闭原则, 是一个非常经典的设计模式, 部分语言已经将装饰模式设计成了一种语法。

    憧憬博客
  • 设计模式~装饰模式

    3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

    Vincent-yuan
  • 设计模式-装饰模式

    cwl_java
  • JavaScript设计模式之装饰器模式

    手机壳就是装饰器,没有它手机也能正常使用,原有的功能不变,手机壳可以减轻手机滑落的损耗。

    FinGet

扫码关注云+社区

领取腾讯云代金券