装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。

1、意图

动态的给一个对象添加额外的功能,装饰者模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

2、适用环境

在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责

处理那些可以撤销的职责

当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类的数量爆炸增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

3、关键代码

Component 类充当抽象角色,不应该具体实现。

修饰类引用和继承 Component 类,具体扩展类重写父类方法。

应用实例

1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

注意事项:可代替继承。

4、参与者

Component(抽象构件角色)

真实对象和装饰对象有相同的接口,这样,客户端对象就能够以与真实对象相同的方式同装饰对象进行交互。

ConcreteComponent(具体构件角色,即真实对象)

IO流中的FileInputStream、FileOutputStream

Decorator(装饰角色)

持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能。

ConcreteDecorator(具体装饰角色)

负责给构件对象增加新的责任。

5、类图

6、涉及角色

抽象组件:定义一个抽象接口,来规范准备附加功能的类。

具体组件:将要被附加功能的类,实现抽象构件角色接口。

抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口。

具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。

7、代码实现

一、创建一个接口

//Shape.java

public interface Shape {

void draw();

}

二、创建实现接口的实体类。

//Rectangle.java

public class Rectangle implements Shape {

@Override

public void draw() {

System.out.println("Shape: Rectangle");

}

}

//Circle.java

public class Circle implements Shape {

@Override

public void draw() {

System.out.println("Shape: Circle");

}

}

三、创建实现了 Shape 接口的抽象装饰类。

//ShapeDecorator.java

public abstract class ShapeDecorator implements Shape {

protected Shape decoratedShape;

public ShapeDecorator(Shape decoratedShape){

this.decoratedShape = decoratedShape;

}

public void draw(){

decoratedShape.draw();

}

}

四、创建扩展了 ShapeDecorator 类的实体装饰类。

//RedShapeDecorator.java

public class RedShapeDecorator extends ShapeDecorator {

public RedShapeDecorator(Shape decoratedShape) {

super(decoratedShape);

}

@Override

public void draw() {

decoratedShape.draw();

setRedBorder(decoratedShape);

}

private void setRedBorder(Shape decoratedShape){

System.out.println("Border Color: Red");

}

}

五、使用 RedShapeDecorator 来装饰 Shape 对象。

public class DecoratorPatternDemo {

public static void main(String[] args) {

Shape circle = new Circle();

ShapeDecorator redCircle = new RedShapeDecorator(new Circle());

ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());

//Shape redCircle = new RedShapeDecorator(new Circle());

//Shape redRectangle = new RedShapeDecorator(new Rectangle());

System.out.println("Circle with normal border");

circle.draw();

System.out.println("\nCircle of red border");

redCircle.draw();

System.out.println("\nRectangle of red border");

redRectangle.draw();

}

}

六、执行程序,输出结果

Circle with normal border

Shape: Circle

Circle of red border

Shape: Circle

Border Color: Red

Rectangle of red border

Shape: Rectangle

Border Color: Red

8、优缺点

1. 优点

装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

2. 缺点

多层装饰比较复杂。

3. 实际使用

这里我们说一下,在java中I/O便使用了装饰者模式。

4. 装饰者用到的设计原则:

多用组合,少用继承。

对扩展开放,对修改关闭。

java设计模式装饰者模式优点_java设计模式之--装饰者模式相关推荐

  1. java 策略模式 促销_java设计模式——策略模式

    一. 定义与类型 定义:针对一组算法,将每一种算法都封装到具有共同接口的独立的类中,从而是它们可以相互替换.策略模式的最大特点是使得算法可以在不影响客户端的情况下发生变化,从而改变不同的功能.当代码中 ...

  2. java外观模式实例_Java设计模式(11)----------外观模式

    1.介绍 外观模式是一种结构型设计模式.在外观模式中,外观类中提供一个或者一组对外的接口.客户端对于复杂系统的访问是通过外观类的接口进行的,从而解除了客户端与复杂系统之间的耦合,隐藏了复杂系统内部的逻 ...

  3. java手动切换成独立显卡_JAVA设计模式之调停者模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述调停者(Mediator)模式的: 调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从 ...

  4. java抽象工厂模式实例_Java设计模式百例 - 抽象工厂模式

    抽象工厂模式是在工厂方法模式之上的有一次升级,以便能够处理更加复杂的对象创建场景.因此也是所有形态的工厂模式中最为抽象和最具一般性的一种形态. 有朋友可能会想了,工厂方法模式已经是对简单工厂模式的具体 ...

  5. java 状态模式 同步_JAVA设计模式之状态模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...

  6. java 工厂模式 计算器_java设计模式之简单工厂模式

    在编写一个计算器程序时,可以将业务逻辑和显示分离,业务逻辑封装为一个类(封装):如果要新添加一种运算,可以先创建一个Operation的基类,然后各种运算从Operation类继承,并实现GetRes ...

  7. java单例模式的七种写法_Java设计模式之单例模式的七种写法

    什么是单例模式? 单例模式是一种常见的设计模式,单例模式的写法有很多种,这里主要介绍三种: 懒汉式单例模式.饿汉式单例模式.登记式单例 . 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类 ...

  8. filter java 是单例的吗_JAVA 设计模式之 单例模式详解

    单例模式:(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.单例模式是创建型模式.单例模式在现实生活中应用也非常广泛. 在 J2EE 标准中,S ...

  9. java 工厂模式实现_Java三种实现工厂模式的方法

    学习工厂模式的时候就曾思考过这么写的好处,再手动敲了代码后发现自己更糊涂了,后来搜索例子和各种文案才有点概念,特此记录一下个人的理解 工厂模式的好处: 1.减少了重复代码 2.让创建对象于使用方法分离 ...

最新文章

  1. 网页文字对齐(CSS)
  2. oracle 树状结构一直出现不了_SEO站内优化:网站结构优化(十一)
  3. IC设计前端几本经典书籍
  4. HashMap中最多只允许一条记录的键为Null,允许多条记录的值为Null
  5. 函数mkdir、mkdirat和emdir
  6. 谈谈CountDownLatch和CyclicBarrier
  7. Context与ApplicationContext
  8. Linux c学习--进程基础学习
  9. Linux 基本网络配置
  10. websocket替代方案_码农手记 | 前后端实时交互方案概述
  11. centos挂载第二块硬盘
  12. rabbitMq多个队列多种任务同时监听
  13. [渝粤教育] 宁波财经学院 创业机会识别 参考 资料
  14. Chrome终极全屏模式Kiosk
  15. linux下刻录光盘读取不了_如何在Linux下刻录数据光盘
  16. CPU连续飙升的背后是 “道德的沦丧” 还是 “人性的泯灭”
  17. 19.Eager模式
  18. java中抛出异常之后程序还会继续运行么?
  19. 2022年全球与中国电缆悬挂夹市场现状及未来发展趋势
  20. WPF-Interaction.Triggers

热门文章

  1. IDEA换背景壁纸及其插件background image plus +
  2. 第2章-Bluetooth® LE audio架构
  3. 数据分析的作用有哪些?
  4. android版iphone6s,iPhone6s现在怎么样,相当于什么档次的安卓机?看完你就明白了...
  5. 本地windows启动nacos报错 ErrCode:500, ErrMsg:jmenv.tbsite.net
  6. python全栈开发
  7. ext 中 columnModel的renderer
  8. DataWorks规划工作空间
  9. 批处理 变量的 两边的引号如何去掉?
  10. mybatis--开发Dao--原始dao方式和Mapper代理方式