博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
装饰者模式
阅读量:4181 次
发布时间:2019-05-26

本文共 2254 字,大约阅读时间需要 7 分钟。

装饰器模式(Decorator Pattern):动态地给对象添加一些额外的职责,就增加功能来说,它比生成子类更为灵活。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

类图及角色

在这里插入图片描述

抽象被装饰角色(component):装饰器模式中公共方法的类,在结构图的顶层。
具体被装饰角色(concrete component):具体被装饰的类。
装饰者角色(decorator):装饰器模式中的核心对象,所有具体装饰器对象的父类,完成装饰器的部分职能。它有个鲜明的特点:继承至component,同时包含一个component成员变量。装饰器模式动机中的动态增加功能就是在这里实现的。
具体装饰对象角色(concrete decorator):继承装饰者,完成具体的装饰功能。装饰功能的实现是通过调用被装饰对象对应的方法,加上装饰对象自身的方法。

装饰器模式的优点和缺点

优点:

1、装饰类和被装饰类可以独立发展,不会相互耦合。
2、装饰模式是继承的一个替代模式,它们的目的都是扩展对象的功能。
3、装饰模式可以动态扩展一个实现类的功能,具有更大的灵活性,动态地决定粘上还是去掉一个装饰;使用继承扩展,这些功能在编译时就确定了,功能是可预见的,是静态的。

缺点:

多层装饰比较复杂。虽然比继承关系使用更少的类,但是使用了更多的对象(更多的对象使查错变得困难,特别使它们还很像的时候)

透明装饰器和不透明装饰器

透明装饰器:整个Decorator的结构中所有的类保持同样的“接口”,这里是共同方法的意思。

不透明装饰器:现实中绝大多数都是不透明的,它们的“接口”在某些子类中得到增强。区分透明和不透明主要看这个类和顶层类或接口是否有同样的公共方法。

//装饰器模式中所有类的父类public abstract class Ingredient {
public abstract String getDescription(); public abstract double getCost(); public void printDescription() {
System.out.println("Name" + this.getDescription()); System.out.println("RMB" + this.getCost()); }}//具体被装饰类public class Bread extends Ingredient {
private String description; public Bread(String description) {
this.description = description; } @Override public String getDescription() {
return description; } @Override public double getCost() {
return 3; }}//装饰者public abstract class Decorator extends Ingredient {
public Ingredient ingredient; public Decorator(Ingredient ingredient) {
this.ingredient = ingredient; } @Override public abstract String getDescription(); @Override public abstract double getCost();}//具体装饰类public class Gerely extends Decorator {
public Gerely(Ingredient ingredient) {
super(ingredient); } @Override public String getDescription() {
String base = ingredient.getDescription(); return base + "\n" + "芹菜"; } @Override public double getCost() {
double basePrice = ingredient.getCost(); return basePrice + 6; }}//具体装饰类public class Pork extends Decorator {
public Pork(Ingredient ingredient) {
super(ingredient); } @Override public String getDescription() {
String base = ingredient.getDescription(); return base + "\n" + "pork"; } @Override public double getCost() {
double basePrice = ingredient.getCost(); return basePrice + 6; }}

上一篇:

下一篇:

转载地址:http://bmrai.baihongyu.com/

你可能感兴趣的文章
SpringBoot多模块项目实践(Multi-Module)
查看>>
第一篇: 服务的注册与发现Eureka(Greenwich版)
查看>>
第二篇: 服务消费者(rest+ribbon)(Greenwich版本)
查看>>
第三篇: 服务消费者(Feign)(Greenwich版本)
查看>>
获取客户的真实IP地址
查看>>
第四篇: 熔断器(Ribbon+Feign)(Greenwich版本)
查看>>
Linux的常用命令(一)
查看>>
Linux的常用命令(二)
查看>>
第六篇: 分布式配置中心(Greenwich版本)
查看>>
SpringBoot | 配置logback-spring.xml
查看>>
SpringBoot | 第一章:构建第一个SpringBoot工程
查看>>
SpringBoot | 第二章:配置多环境以及上传文件
查看>>
Spring Data JPA |自定义非实体类的映射
查看>>
SpringBoot | 常用注解记录
查看>>
JavaBean对象转换EntityUtils工具类
查看>>
Maven常用命令
查看>>
SpringBoot | 运行报错,无法加载oracle连接驱动
查看>>
为什么阿里巴巴禁止在 foreach 循环里进行元素的 remove/add 操作
查看>>
AWS EC2如何从普通用户切换为root用户
查看>>
click方法不生效的
查看>>