当前位置:首页 > > 程序员小灰
[导读]什么是 “装饰器模式” ?



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


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










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


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—————


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭