设计模式23---设计模式之装饰模式(Decorator)(结构型)
1.装饰模式讲解
1.1定义
动态的给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更加灵活。
1.2装饰模式要点
透明的给一个对象增加功能,换句话说就是要给一个对象增加功能,但是不能让这个对象知道,也就是不能去改动这个对象。
面向对象设计的一个基本规则就是:尽量使用对象组合,而不是使用对象继承。
装饰者和被装饰对象有相同的超类型。
可以用一个或多个装饰者包装一个对象。
装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。
对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。
装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为。
装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。在实际项目中可以根据需要为装饰者添加新的行为,做到“半透明”装饰者。
适配器模式的用意是改变对象的接口而不一定改变对象的性能,而装饰模式的用意是保持接口并增加对象的职责。
1.3装饰模式的结构图和说明
抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。
1.4装饰模式示例代码
package demo21.decorator.example3;
/**
* 组件对象的接口,可以给这些对象动态的添加职责
*/
public abstract class Component {
/**
* 示例方法
*/
public abstract void operation();
}
***************************************************************************************************
package demo21.decorator.example3;
/**
* 具体实现组件对象接口的对象
*/
public class ConcreteComponent extends Component { public void operation() {
//相应的功能处理
}
}
**************************************************************************************************
package demo21.decorator.example3;
/**
* 装饰器接口,维持一个指向组件对象的接口对象,
* 并定义一个与组件接口一致的接口
*/
public abstract class Decorator extends Component {
/**
* 持有组件对象
*/
protected Component component;
/**
* 构造方法,传入组件对象
* @param component 组件对象
*/
public Decorator(Component component) {
this.component = component;
} public void operation() {
//转发请求给组件对象,可以在转发前后执行一些附加动作
component.operation();
}
}
**************************************************************************************************
package demo21.decorator.example3;
/**
* 装饰器的具体实现对象,向组件对象添加职责
*/
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
/**
* 添加的状态
*/
private String addedState; public String getAddedState() {
return addedState;
} public void setAddedState(String addedState) {
this.addedState = addedState;
} public void operation() {
//调用父类的方法,可以在调用前后执行一些附加动作
//在这里进行处理的时候,可以使用添加的状态
super.operation();
}
}
**************************************************************************************************
package demo21.decorator.example3; /**
* 装饰器的具体实现对象,向组件对象添加职责
*/
public class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
/**
* 需要添加的职责
*/
private void addedBehavior() {
//需要添加的职责实现
}
public void operation() {
//调用父类的方法,可以在调用前后执行一些附加动作
super.operation();
addedBehavior();
}
}
1.5装饰模式的本质
动态结合
1.6装饰模式的优缺点
优点:
比继承更加灵活
更容易复用功能
简化高层定义
缺点:
会产生很多细粒度对象
1.7何时选用
如果需要以动态透明的方式给对象添加职责,可以使用装饰模式
如果不适合使用子类来进行扩展的时候,可以考虑使用装饰模式
2.举例说明装饰模式
最最常见的例子就是java中的I/O数据流了,大家有时间可以看看他的继承实现结构图
假如你刚刚买了一辆汽车,是一个裸车,他不符合你的自己的个性化的要求,比如说外观不好看,轮胎不好,发动机马力不足等等。那么你就需要对外表进行装饰,换换颜色,把车里面增加一些坐垫。那么,这里就需要用到我们刚刚学过的装饰模式。
实例代码如下,代码注释的很清楚,我就不再赘述了
2.1对应Component
package demo21.decorator.example1; /**
* 组件对象---车
*
* @author 王玉超
*
*/
public abstract class Car {
/**
* 行驶功能
*/
public abstract void run();
}
2.2对应ConcreteComponent
package demo21.decorator.example1; /**
* 具体的车,假如是奥迪
*
* @author 王玉超
*
*/
public class AudiCar extends Car { @Override
public void run() {
System.out.println("奥迪行驶在马路上...");
} }
2.3对应Decorator
package demo21.decorator.example1; /**
* 装饰器接口,维持一个指向组件对象的接口对象, 并定义一个与组件接口一致的接口,这是是装饰的接口
*/
public abstract class Decorator extends Car {
/**
* 持有组件对象
*/
private Car car; /**
* 构造方法,传入组件对象
*
* @param car
* 组件对象
*/
public Decorator(Car car) {
this.car = car;
} @Override
public void run() {
// 转发给component组件对象car
this.car.run();
}
}
2.4对应 ConcreteDecoratorA
package demo21.decorator.example1; /**
* 装饰器的具体实现对象,向组件对象添加职责 ,这个是添加颜色的车
*/
public class AddColorCar extends Decorator {
public AddColorCar(Car car) {
super(car);
} /**
* 添加的状态,更改外观
*/
private String face; public void setFace(String face) {
this.face = face;
} public void addColor() {
System.out.println("我添加了颜色" + this.face);
} @Override
public void run() {
// 调用父类的方法,可以在调用前后执行一些附加动作
// 在这里进行处理的时候,可以使用添加的状态
super.run(); this.addColor();
}
}
2.5对应 ConcreteDecoratorB
package demo21.decorator.example1; /**
* 装饰器的具体实现对象,向组件对象添加职责 ,这个是添加坐垫的车
*/
public class AddSeatCar extends Decorator {
public AddSeatCar(Car car) {
super(car);
} /**
* 添加的状态,添加坐垫
*/
private String seat; public void setSeat(String seat) {
this.seat = seat;
} public void addSeat() {
System.out.println("我添加了坐垫" + this.seat);
} @Override
public void run() {
// 调用父类的方法,可以在调用前后执行一些附加动作
// 在这里进行处理的时候,可以使用添加的状态
super.run(); this.addSeat();
}
}
2.6客户端使用
package demo21.decorator.example1; public class Client {
public static void main(String[] args) {
// 被装饰的对象
Car car = new AudiCar();
// 装饰者对象
Decorator colorCar = new AddColorCar(car);
((AddColorCar) colorCar).setFace("红色"); Decorator seatCar = new AddSeatCar(colorCar);
((AddSeatCar) seatCar).setSeat("夏天清凉坐垫"); // 汽车跑起来吧
seatCar.run();
}
}
如何看完以后,还是不明白,我建议读者看看java I/O数据流里面的各种类,以及他们之间的关系,或许就明白了。
设计模式23---设计模式之装饰模式(Decorator)(结构型)的更多相关文章
- 设计模式09: Decorator 装饰模式(结构型模式)
Decorator 装饰模式(结构型模式) 子类复子类,子类何其多加入我们需要为游戏中开发一种坦克,除了不同型号的坦克外,我们还希望在不同场合中为其增加以下一种多种功能:比如红外线夜视功能,比如水路两 ...
- 修饰模式(Decorator结构型)C#简单例子
修饰模式(Decorator结构型)C#简单例子 玩家基本功能是移动.运行等等.BaseAbility新增加功能:1.伤害技能harmAbility:2.阻碍技能BaulkAbility:3.辅助技能 ...
- Java开发中的23种设计模式详解(2)结构型
我们接着讨论设计模式,上篇文章我讲完了5种创建型模式,这章开始,我将讲下7种结构型模式:适配器模式.装饰模式.代理模式.外观模式.桥接模式.组合模式.享元模式.其中对象的适配器模式是各种模式的起源,我 ...
- (转)Java经典设计模式(2):七大结构型模式(附实例和详解)
原文出处: 小宝鸽 总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式 ...
- 设计模式(11)--Flyweight(享元模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 2.模式特点: 享元模 ...
- 设计模式06: Adapter 适配器模式(结构型模式)
Adapter 适配器模式(结构型模式) 适配(转换)的概念无处不在:电源转接头.电源适配器.水管转接头... 动机(Motivation)在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象 ...
- 大话设计模式宏观总结——创建型&结构型&行为型
师傅验收项目的时候.问大话设计模式那三种类型的差别和联系是什么,顿时我傻了眼.由于除了知道这三种类型分别如何称呼以外.从来都没想过为什么这样划分?于是,我便回答:我没想过这个问题.若是从字面上来理解的 ...
- 装饰器模式 Decorator 结构型 设计模式 (十)
引子 现实世界的装饰器模式 大家应该都吃过手抓饼,本文装饰器模式以手抓饼为模型展开简介 "老板,来一个手抓饼, 加个培根, 加个鸡蛋,多少钱?" 这句话会不 ...
- 设计模式-Decorator(结构型模式) 用于通过 组合 的方式 给定义的类 添加新的操作,这里不用 继承 的原因是 增加了系统的复杂性,继承使深度加深。
以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Decorator.h #pragma once class Component { public: virtual ~C ...
- 设计模式(8)--Decorator--装饰器模式--结构型
1.模式定义: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 2.模式特点: 装饰模式能够实现动态的为对象添加功能,是从一个对象 ...
随机推荐
- 修改netbeans模版头部的说明
以新建一个php类文件为例: 有两个地方需要修改, 1,工具->模版->默认许可证->在编辑器中打开 2,工具->模版->选择php类->在编辑器中打开 即可进行修 ...
- thinkphp 减少文件目录
配置 'TMPL_FILE_DEPR'=>'_' 于是模板文件的格式为如:index_index.html,index_show.html .代替原来的目录结构:/index/index.htm ...
- MSSQLServer基础05(联合查询,连接查询)
联合结果集union(集合运算符) 集合运算符是对两个集合操作的,两个集合必须具有相同的列数,列具有相同的数据类型(至少能隐式转换的),最终输出的集合的列名由第一个集合的列名来确定.(可以用来连接多个 ...
- MSSQLServer基础04(常用函数)
类型转换函数 CAST ( expression AS data_type) CONVERT ( data_type, expression,[style]) 对日期的转换.转换成各种国家格式的日期. ...
- android系统平台显示驱动开发简要:LCD驱动调试篇『四』
平台信息: 内核:linux3.4.39系统:android4.4 平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新浪博 ...
- NFC(10)NDEF uri格式规范及读写示例(解析与封装ndef uri)
只有遵守NDEF uri 格式规范的数据才能写到nfc标签上. NDEF uri 格式规范 uri 只有两部分: 第1个字节是uri协议映射值,如:0x01 表示uri以 http://www.开头. ...
- java中synchronized的用法详解
记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...
- poj3257
dp,先将材料按以终点为关键字升序排 设f[i,j]为过山车到建到位置i在用了j元钱所得到的最大价值,然后 ..] of longint; f:..,..] of longint; l,n,k,m,j ...
- DTD约束文件
在讲解DTD文件之前,我要说说一份合格的XML应该符合怎么样的规则? 就我总结一下几点,大家看看就好了: 1.一份XML有且仅有一个根元素. 2.XML是严格区分大小写的,<book>元素 ...
- Java [leetcode 12] Integer to Roman
题目描述: Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range fr ...