装饰器模式(Decorator)
一、装饰模式介绍
装饰模式(decorator):表示动态的给一个对象添加一些新的功能(利用子类继承父类也可以实现),但是比生成子类方式更灵活。
也叫装饰者模式或者装饰器模式
例如:我们每个人身上穿的衣服,鞋子,领带,披风都可以理解为是对人的装饰。
装饰器模式类图:

Component:定义一个对象接口,可以给这些对象动态添加职责。真实对象和装饰者对象有相同的接口,这样客户端不用知道内部有装饰者对象(Decorator)
存在的,还是以之前处理真实对象的相同方式来和装饰者对象交互。
ConcreteComponent:是定义了一个具体的对象(例如:人),也可以给这个对象添加一些其他职责。
Decorator:装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对Component来说,是无需知道Decorator存在的。
ConcreteDecorator:就是具体的装饰对象了(衣服,鞋子..),它起到了给Component添加职责的功能。
二、装饰模式代码实现
定义一个Component对象接口(ICar),汽车移动
|
1
2
3
4
5
6
|
/** * ICar表示Component: */public interface ICar { void move();//汽车移动} |
定义一个具体真实的对象ConcreteComponent:这里是Car,就是具体的汽车,未装饰的汽车
|
1
2
3
4
5
6
7
|
//ConcreteComponent:具体的对象class Car implements ICar{ @Override public void move() { System.out.println("汽车移动"); }} |
装饰抽象类Decorator:SuperCar这里需要持有一个真实对象的引用,也就是Car对象
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//Decorator:装饰抽象类class SuperCar implements ICar{ protected ICar car;//持有一个真实对象的引用 @Override public void move() { car.move();//这里调用真实对象的移动方法 } //构造的时候传参 public SuperCar(ICar car) { super(); this.car = car; }} |
开始实现具体的装饰对象ConcreteDecorator:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
//ConcreteDecorator:就是具体的装饰对象class FlayCar extends SuperCar { public FlayCar(ICar car) { super(car); } //这里就是新增的功能 public void flay(){ System.out.println("---天上飞"); } @Override public void move() { super.move(); flay();//在原有移动的基础上,装饰了一个fly的功能 }}//ConcreteDecorator:就是具体的装饰对象class WaterCar extends SuperCar { public WaterCar(ICar car) { super(car); } //这里就是新增的功能 public void swim(){ System.out.println("---水里游"); } @Override public void move() { super.move(); swim();//在原有移动的基础上,装饰了一个swim的功能 }} |
测试代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public static void main(String[] args) { Car car = new Car(); car.move();//这里打印未增加新功能的时候:汽车移动 System.out.println("--------增加飞行功能-------"); FlayCar flyCar = new FlayCar(car);//将真实对象传入装饰对象中 flyCar.move();//这里就是增加了飞行后的装饰 System.out.println("--------增加潜水功能-------"); WaterCar waterCar = new WaterCar(car);//将真实对象传入装饰对象中 waterCar.move();//这里就是增加了潜水功能后的装饰 } |
控制台结果就是:
汽车移动
--------增加飞行功能-------
汽车移动
---天上飞
--------增加潜水功能-------
汽车移动
---水里游
整个例子的类图结构如下:

三、总结
装饰模式(Decorator)也叫包装器模式(Wrapper)
装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化
以便增加新的具体构建类和具体装饰类。
优点:
扩展功能强,相比继承来说更灵活。继承的话会导致子类个数增加。而装饰者模式不会出现这种情况。
可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象。
具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的构件子类和具体装饰类。
缺点:
产生很多小对象,大量小对象会占据内存。一定程度上影响了性能。
装饰模式易于出错,调试排查比较麻烦。
开发中应用的场景:
IO中输入流和输出流
Swing包中图形界面构件功能
Servlet API中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,增强了request对象的功能。
Struts2中,request,response,session对象的处理。
装饰模式和桥接模式的区别:
两个模式都是为了解决过多子类对象的问题,桥接模式是对象自身有过多的维度,造成过多的子类。而让维度分类后在搭建一个桥梁来联系起来。
而装饰模式是解决在增加新功能的时候产生多个类的问题。
参考资料:
大话设计模式(带目录完整版).pdf
HEAD_FIRST设计模式(中文版).pdf
尚学堂_高淇_java300集最全视频教程_【GOF23设计模式】
装饰器模式(Decorator)的更多相关文章
- 【PHP设计模式 09_ZhuangShiQi.php】装饰器模式 (decorator)
<?php /** * [装饰器模式 (decorator)] * 有时候发布一篇文章需要经过很多人手,层层处理 */ header("Content-type: text/html; ...
- 设计模式(八)装饰器模式Decorator(结构型)
设计模式(八)装饰器模式Decorator(结构型) 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法 ...
- 装饰器模式-Decorator(Java实现)
装饰器模式-Decorator(Java实现) 装饰器模式允许向一个现有的对象添加新的功能, 同时又不改变其结构. 其中 "现有对象"在本文中是StringDisplay类. 添加 ...
- 说说设计模式~装饰器模式(Decorator)~多功能消息组件的实现
返回目录 为何要设计多功能消息组件 之前写过一篇装饰器模式的文章,感觉不够深入,这次的例子是实现项目中遇到的,所以把它拿出来,再写写,之前也写过消息组件的文章,主要采用了策略模式实现的,即每个项目可以 ...
- 装饰器模式(Decorator)
转自http://blog.csdn.net/hust_is_lcd/article/details/7884320 1.认识装饰器模式 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象 ...
- 设计模式入门之装饰器模式Decorator
//装饰模式定义:动态地给一个对象加入一些额外的职责. //就添加功能来说.装饰模式比生成子类更为灵活 //这也提现了面向对象设计中的一条基本原则,即:尽量使用对象组合,而不是对象继承 //Compo ...
- 装饰器模式(Decorator)——深入理解与实战应用
本文为原创博文,转载请注明出处,侵权必究! 1.初识装饰器模式 装饰器模式,顾名思义,就是对已经存在的某些类进行装饰,以此来扩展一些功能.其结构图如下: Component为统一接口,也是装饰类和被装 ...
- 装饰器模式 Decorator 结构型 设计模式 (十)
引子 现实世界的装饰器模式 大家应该都吃过手抓饼,本文装饰器模式以手抓饼为模型展开简介 "老板,来一个手抓饼, 加个培根, 加个鸡蛋,多少钱?" 这句话会不 ...
- 设计模式学习心得<装饰器模式 Decorator>
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...
- 23种设计模式之装饰器模式(Decorator Pattern)
装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...
随机推荐
- 实用crontab命令
常用crontab如下: crontab -e 编辑 crontabcrontab -l 显示 crontabcrontab -r 删除 crontabcrontab -v 显示上一次编辑 cro ...
- python内置函数之print()
定义:将值打印到一个流对象,或者默认打印到sys.stdout. 语法: print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=Fal ...
- asp.net添加用户
AddUser.html <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <h ...
- Pgsql特殊排序
对字段值为A,B,C,D的时候进行特殊排序. CASE WHEN aa = 'H' THEN ' WHENaa = 'O' THEN ' ELSE aa END 对数字进行排序,升序,0排到最后面 C ...
- C语言 · Sine之舞
基础练习 Sine之舞 时间限制:1.0s 内存限制:512.0MB 问题描述 最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功.所以他准备和奶 ...
- sama5d3 环境检测 adc测试
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h># ...
- CSS——div居中,window.open(0
margin:0 auto 表示什么意思?? margin后面如果只有两个参数的话,第一个表示top和bottom,第二个表示left和right因为0 auto,表示上下边界为0,左右则根据宽度自适 ...
- TF和SD
TF卡又称T-Flash卡,全名:TransFLash,又名:Micro SD SD卡(Secure Digital Memory Card,安全数码卡)
- 离线 + 位优化 - SGU 108 Self-numbers 2
SGU 108 Self-numbers 2 Problem's Link Mean: 略有这样一种数字:对于任意正整数n,定义d(n)为n加上n的各个位上的数字(d是数字的意思,Kaprekar发明 ...
- 011杰信-创建购销合同Excel报表系列-4-建立合同货物(修改,删除):合同货物表是购销合同表的子表
前面的一篇文章做的是修改删除,这篇文章做的是合同货物的修改和删除. 业务功能如下: