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

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

大话设计模式中程杰老师给出的定义,装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。

装饰模式结构图如下:

关键代码:

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

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

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

类图如下:

//抽象Shape接口,可以给这些对象添加职责
package com.dfcDemo;public interface Shape {public abstract void draw();
}
//具体形状对象,可以给这些对象添加职责
package com.dfcDemo;public class Circle implements Shape{@Overridepublic void draw() {System.out.println("shape:circle.");}}
//具体形状对象,可以给这些对象添加职责
package com.dfcDemo;public class Rectangle implements Shape{@Overridepublic void draw() {System.out.println("shape:rectangle.");}}
package com.dfcDemo;
/*** Shape接口的抽象装饰类* @author lmb**/
public abstract class ShapeDecorator implements Shape{public Shape decoratedShape;//ShapeDecorator类中要向构造方法传入一个被装饰的对象public ShapeDecorator(Shape decoratedShape){this.decoratedShape = decoratedShape;}@Overridepublic void draw() {decoratedShape.draw();      }}
//Shape接口的具体装饰类,继承自抽象装饰类SHapeDecorator
package com.dfcDemo;public class RedShapeDecorator extends ShapeDecorator{public RedShapeDecorator decoratedShape;//构造方法传入一个被装饰的Shape对象public RedShapeDecorator(Shape decoratedShape) {super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw();//画出一个图形           setRedBorder(decoratedShape);//为这个图形加一个红色的边框}//Shape接口抽象装饰类的子类RedShapeDecorator特有的一个装饰Shape实现类的装饰方法private void setRedBorder(Shape decoratedShape){System.out.println("Border Color: Red");}}
//测试类
package com.dfcDemo;public class TestDecorator {public static void main(String[] args) {Shape circle = new Circle();Shape redCircle = new RedShapeDecorator(new Circle());Shape redRectangle = new RedShapeDecorator(new Rectangle());System.out.println("Circle with normal border");circle.draw();//1、画图形  System.out.println("\nCircle of red border");redCircle.draw();//1、画图形  2、加红色边框System.out.println("\nRectangle of red border");redRectangle.draw();//1、画图形  2、加红色边框}}

运行结果:

Circle with normal border
shape:circle.Circle of red border
shape:circle.
Border Color: RedRectangle of red border
shape:rectangle.
Border Color: Red

在该实例中装饰模式是利用setBorder()来对对象进行包装。这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链中。

装饰模式是为已有的功能动态地添加更多功能的一种方式。但到底我们什么时候能用到呢?

当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责和行为,比如用红色边框装饰Circle和Rectangle,但这种做大的问题在于,他们在主类中加入了新的字段、新的方法和新的逻辑,从而增加了主类的复杂度,就像起初的那个Shape类,而这些新加入的东西仅仅是对了满足一些只在某种特定情况下才会执行的特殊行为的需要。而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要的对象,因此,当需要执行特殊行为时,客户端代码就可以在运行时根据需要有选择的、按顺序的使用装饰功能包装对象。

这样我们可以总结出:

装饰模式的优点:把类中的装饰功能从类中去掉,这样可以简化原有的类,这样就能有效的把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑;简而言之,装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

装饰模式的缺点:多层装饰比较复杂。

使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。

注意事项:可代替继承

大话设计模式—装饰模式相关推荐

  1. 大话设计模式——装饰模式

    需求 写一个给人模拟搭配不同服饰的程序,可以给人换各种各样的衣服裤子的形象. 初步实现 需求比较简单,直接上代码: public class Person {private String name;p ...

  2. 大话设计模式-装饰模式(大鸟和小菜Java版)

    装饰模式:装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象.(百度百科) 这个模式让后期的修改变得极为简单,真的就高内 ...

  3. 大话设计模式装饰模式c++实现

    装饰模式 其他二十三种设计模式 #include<iostream>using namespace std;//装饰模式 //人类 class Person {public:Person( ...

  4. 由浅入深大话设计模式——装饰模式

    今天我们从一个日常每个人都会接触的地方下手--换装,人靠衣服马靠鞍,衣服确实能提升一个人的外表分数(可是我就不会 = =),那如果让你做一个给人搭配不同衣服的系统你会怎么做呢? 下面我们设计一个程序: ...

  5. 大话设计模式-装饰模式

    前言 穿衣打扮是现在的时尚潮流,我们时常刷淘宝来不断满足自己的打扮需求,买个帽子.换条裤子.整双时尚鞋.需求是没有极限的,无止境的购物,只要存在这个平台那么这些装饰性的购物是不可避免的.这在我们软件开 ...

  6. 【大话设计模式】设计模式系统学习大合集

    转载请注明出处:http://blog.csdn.net/column/details/designpatternbylmb.html 为了方便各位网友学习以及方便自己复习之用,将设计模式的系列内容按 ...

  7. 大话设计模式C++版——装饰模式

           女人常说男人喜新厌旧.仅仅见新人笑,那闻旧人哭,但装饰模式(Decorator)却是一种结交新朋友不忘老朋友的设计模式,很适合去古代当老公(现代是不行的.由于仅仅能娶一个老婆了).装饰模 ...

  8. 大话设计模式之装饰模式(python实现)

    大话设计模式之装饰模式 使用场景 定义 装饰模式结构图 python实现装饰模式 代码结构图 优点 使用场景 建造过程不稳定,不确定.把所需的功能按照正确的顺序串联起来进行控制. 新加入的东西仅仅是为 ...

  9. 【Python】《大话设计模式》Python版代码实现

    <大话设计模式>Python版代码实现 上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼 ...

最新文章

  1. 通过改进团队流程最大限度发挥Scrum的优势
  2. Javascript 中 apply、call、bind
  3. seaborn系列 (16) | 变量关系组图pairplot()
  4. 3维DEMO: 抽奖圆盘
  5. 2008年1月19日 微软(北京).NET俱乐部 线下休闲活动-滑雪
  6. 修改Linux内核启动图片
  7. 阴阳师服务器维护稍后,《阴阳师》手游3月20日维护更新公告
  8. LAMP环境安装与apache配置
  9. hibernate 多条件组合查询之sql拼接
  10. 04 | 函数与优化方法:模型的自我学习(上)
  11. 如何打造园本特色_如何确立办园特色
  12. Android实现图片的高效批量加载
  13. 测试人员的发展瓶颈:35岁之后我们该何去何从...
  14. 设计模式之行为类模式大PK
  15. html把毫秒转换成年月日,JS实现获取毫秒值及转换成年月日时分秒的方法
  16. 微信小程序如何搭建自己的后台(超详细,超完整)(上线必备)!!!
  17. 80后早期的我们,为什么还拽着青春的尾巴不结婚呢?
  18. WordPress个人博客Cosy3.1.3主题+积木部分插件
  19. HIVE获取时间函数, regexp_extract正则提取用法
  20. 逝者已逝,愿生者坚强

热门文章

  1. 安全研究剖析:******方式演示
  2. mysql主从同步监控小脚本(加强版)
  3. 知道Google map上面街景怎么来的吗?-相当强大
  4. NFS 服务学习笔记
  5. 【性能优化】 之 并行执行
  6. Java 对象的序列化和反序列化
  7. android EventBus的简单使用
  8. Sysnoise5.6安装教程
  9. 攻防:如何防止动态hook绕过jni签名校验
  10. “android:process“---由日志引发的大灾难