设计模式~装饰模式
装饰模式(Decorator)又名包装模式(Wrapper)。
装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
装饰模式以对客户端透明的方式动态的给一个对象附加上更多的责任。
装饰模式的结构
模式的类图
角色如下:
- 抽象构件角色(Component): 给出一个抽象接口,以规范准备接受附加责任的对象。
- 具体构件角色(Concrete Component): 定义一个将要接收附加责任的类
- 装饰角色(Decorator): 持有一个构建(Component)对象的实例,并定义一个与抽象角色接口一致的接口。
- 具体装饰角色(Concrete Decorator): 负责给构建对象贴上附加的责任。
代码清单
构建类 Component
/**
* 构建类
* @author Administrator
*
*/
public interface Component {
/**
* 商业方法
*/
void sampleOperation();
}
装饰类 Decorator
public class Decorator implements Component {
private Component component;
public Decorator(Component component){
this.component = component;
}
public Decorator(){
//write your code
}
/**
* 商业方法,委派给构件
*/
@Override
public void sampleOperation() {
// TODO Auto-generated method stub
component.sampleOperation();
}
}
具体构件类 ConcreteComponent
public class ConcreteComponent implements Component {
public ConcreteComponent(){
}
/**
* 商业方法
*/
@Override
public void sampleOperation() {
}
}
具体装饰类
public class ConcreteDecorator extends Decorator {
/**
* 商业方法
*/
public void sampleOperation()
{
super.sampleOperation();
}
}
装饰模式应当在什么情况下使用
1. 需要扩展一个类的功能,或给一个类增加附加责任。
2. 需要动态的给一个对象增加功能,这些功能可以再动态的撤销。
3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
装饰模式的优点和缺点
优点:
1 . 装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
3. 这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错。
缺点:
使用装饰模式,可以比使用继承关系需要较少数目的类。
使用较少数目的类,当然使设计比较易于进行。
使用装饰模式会产生比使用继承关系更多的对象。
更多的对象会使的查错变的困难,特别是这些对象看上去都很相像。
模式的简化
大多数情况下,装饰模式的实现都比本节定义中给出的示意性实现要简单。
对模式进行简化时,要注意以下情况:
1. 一个装饰类的接口必须与被装饰类的接口相容。
2. 尽量保持 Component 作为一个轻类。
这个类的责任是为各个 ConcreteDecorator 类提供共同的接口,因此它应当着重在提供接口而不是存储数据。
3. 如果只有一个ConcreteComponent 类而没有抽象的 Component 类(接口),那么Decorator类经常可以是ConcreteCompoent的一个子类。
4. 如果只有一个ConcreteDecorator类,那么就没必要建立一个单独的 Decorator 类,可以把Decorator 和 ConcreteDecorator 的责任合并成一个类。
一个例子:发票系统
假设只有一个头部装饰类和一个尾部装饰类,设计图如下:
- 如何在CDH集群使用HDFS快照
- Sentry赋予server1权限给hive以外用户时ACL不同步问题分析
- 如何使用Java连接Kerberos的HBase
- 香香的xss小记录(一)
- UAF Writeup - pwnable.kr
- 如何使用Nginx实现Impala负载均衡
- pwnhub年前最后一战——“血月归来”writeup
- MHN中心服务器搭建与树莓派蜜罐部署
- 如何在CDH中启用Spark Thrift
- 让你的以太坊 DApps 盈利的 6 种方法
- 赛博地球杯初赛第三名,ChaMd5安全团队的writeup
- 如何在Windows Server2012搭建DNS服务并配置泛域名解析
- 如何使用HBase快照实现跨集群全量与增量数据迁移
- 为什么你应该学习搭建区块链应用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android自定义View实现地铁显示牌效果
- Android自定义控件实现望远镜效果
- Android自定义View实现点赞控件
- Android自定义View实现投票进度条
- 国外Reservo一款非常棒的商业图床程序
- 详解Android v1、v2、v3签名(小结)
- Android Studio项目适配AndroidX(Android 9.0)的方法步骤
- Android自定义View实现微信语音界面
- Android仿微信录音功能(录音后的raw文件转mp3文件)
- Android基于腾讯云实时音视频仿微信视频通话最小化悬浮
- Android自定义View之RadioGroup实现跨多行显示
- Android RadioGroup多行显示效果 解决单选问题
- RadioGroup实现单选框的多行排列
- Android实现悬浮窗全系统版本
- Android基础控件RadioGroup使用方法详解