装饰模式是一种比较常见的模式。

定义为:动态的给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更加灵活。

装饰模式的通用类图如下:



装饰模式的构成:

1) 抽象构件(Component):是一个接口或者是抽象类,就是定义我们最核心的对象,也就是原始的对象。

******在装饰模式中必须有一个最基本,最核心,最原始的接口或者抽象类来充当Component抽象构件******

2) 具体构件(ConcreteComponent):是最核心,最原始,最基本的接口或者抽象类的实现,你要装饰的就是它

3)    装饰角色(Docorator):一般是一个抽象类,做什么用呢?实现接口或者抽象方法,它里面可不一定有抽象方法呀,在它的属性里必然有一个private变量指向Component抽象构件。

4)    具体装饰角色(ConcreteDecoratorA和B):是两个具体的装饰类,你要把你最核心,最原始,最基本的东西装饰成其他东西。

 装饰模式与类继承的区别:

1)    装饰模式是一种动态行为,对已经存在类进行随意组合,而类的继承是一种静态的行为,一个类定义成什么样的,该类的对象便具有什么样的功能,无法动态的改变。

2)    装饰模式扩展的是对象的功能,不需要增加类的数量,而类继承扩展是类的功能,在继承的关系中,如果我们想增加一个对象的功能,我们只能通过继承关系,在子类中增加两个方法。

3)    装饰模式是在不改变原类文件和使用继承的情况下,动态的扩展一个对象的功能,它是通过创建一个包装对象,也就是装饰来包裹真是的对象。

  装饰模式的特点:

1)    装饰对象和真实对象具有相同的接口,这样客户端对象就可以以真实对象的相同的方式和装饰对象交互。

2)    装饰对象包含一个真实对象的引用(reference).

3)    装饰对象接受所有来自客户端的请求,它把这些请求转发给真实的对象。

4)    装饰对象可以在转发这些请求以前或者以后增加一些附加的功能。这样就能确保在运行时,不用修改给定对象结构就可以在外部增加附加的功能。在面向对象的程序设计中,通常是使用继承的关系来扩展给定类的功能。

来分析一个例子:

package zhuangshimoshi;
/*
* 装饰模式
*/
public class Test { public static void main(String[] args) {
//要修饰的对象com
Component com=new ConcreteComponent(); //进行第一次修饰
com=new ConcreteDecorator1(com); //进行第2次修饰
com=new ConcreteDecorator2(com); com.operate(); //com=new ConcreteDecorator2(new ConcreteDecorator1(new ConcreteComponent())); } } //抽象构件
abstract class Component{
//抽象方法
public abstract void operate();
} //具体构件
class ConcreteComponent extends Component{ //具体实现
public void operate() {
System.out.println("这里是具体构件,实现了抽象构件中的方法");
} } //抽象装饰者,一般为一个抽象类
abstract class Decorator extends Component{
//必须有一个private变量指向Component抽象构件
private Component component;
//通过构造函数传递被修饰者
public Decorator(Component component)
{
System.out.println("这里是抽象类Decortor...");
this.component=component;
} //委托给被修饰者执行
public void operate()
{
System.out.println("父类的操作方法...");
this.component.operate();
}
} //具体的装饰类
class ConcreteDecorator1 extends Decorator{ //定义被装饰者
public ConcreteDecorator1(Component component) {
super(component); }
//定义自己的修饰方法
private void method1()
{
System.out.println("method1修饰。。。");
} //重写父类的operate方法
public void operate()
{
this.method1();
super.operate();
} } class ConcreteDecorator2 extends Decorator{ //定义被装饰者
public ConcreteDecorator2(Component component) {
super(component); }
//定义自己的修饰方法
private void method2()
{
System.out.println("method2修饰。。。");
} //重写父类的operate方法
public void operate()
{
super.operate();
this.method2();
} }

输入结果如图所示:

分析1:主函数中执行了com=new ConcreteDecorator1(com);这个语句,将调用ConcreteDecorator1的构造函数,接着调用父类的构造函数,所以输出了一句“这里是抽象类Decortor...”。

分析2:同理执行了com=new ConcreteDecorator2(com);也输出了“这里是抽象类Decortor...”。

分析3:执行了com.operate(),首先是ConcreteDecorator2类的operate()方法被执行,即super.operate();,此时要执行其父类的operate()。父类Decorator的operate()方法被执行,输出了“父类的操作方法...”。

分析4:接着执行this.component.operate();语句。注意了!!!!此时component对象指的是ConcreteDecorator1类的对象,即将要执行的ConcreteDecorator1类中的operate()方法,所以输出了"method1修饰。。。"

分析5:接着执行super.operate();语句,又回到父类Decorator中的operate()方法,输出了“父类的操作方法...”。

分析6:接着执行this.component.operate();语句。注意了!!!!此时component对象指的是ConcreteComponent类的对象,所以执行ConcreteComponent类的operate()方法。所以输出了"这里是具体构件,实现了抽象构件中的方法"。

分析7:最后执行this.method2();语句,输出"method2修饰。。。"

以上是本例的详细解释,得多看几遍细细领悟才行。

Java设计模式—装饰模式的更多相关文章

  1. Java设计模式---装饰模式

    装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的结构 装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任.换言之,客户 ...

  2. Java设计模式-装饰模式(Decorator)

    顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,关系图如下: Source类是被装饰类,Decorator类是一个 ...

  3. Java设计模式——装饰模式

    转载自:http://blog.csdn.net/xu__cg/article/details/53024490 抽象构件 public interface CarInterface { void m ...

  4. Java设计模式学习记录-装饰模式

    前言 装饰模式也是一种结构型模式,主要是目的是相对于类与类之间的继承关系来说,使用装饰模式可以降低耦合度.JDK中有不少地方都使用到了装饰模式,例如Java的各种I/O流,javax.swing包中一 ...

  5. Java设计模式(7)装饰模式(Decorator模式)

    Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...

  6. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

  7. Java设计模式(十二) 策略模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/design_pattern/strategy/ 策略模式介绍 策略模式定义 策略模式(Strategy Pattern) ...

  8. Java设计模式(二) 工厂方法模式

    本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...

  9. Java设计模式(一) 简单工厂模式不简单

    摘要:本文介绍了简单工厂模式的概念,优缺点,实现方式,以及结合Annotation和反射的改良方案(让简单工厂模式不简单).同时介绍了简单工厂模式(未)遵循的OOP原则.最后给出了简单工厂模式在JDB ...

随机推荐

  1. shell if的使用

    1 字符串判断 str1 = str2 当两个串有相同内容.长度时为真 str1 != str2 当串str1和str2不等时为真 -n str1 当串的长度大于0时为真(串非空) -z str1 当 ...

  2. c/c++转义字符大全【转自互联网】

    将转义字符收集如下:转义字符 意义 ASCII码值(十进制) \a 响铃(BEL) 007 \b 退格(BS) 008 \f 换页(FF) 012 \n 换行(LF) 010 \r 回车(CR) 01 ...

  3. 图解Laravel的生命周期

    先来张图大致理解下laravel的生命周期. 下面对应相应的代码,解释上图. //文件路径:laravel/public/index.php /** * laravel的启动时间 */ define( ...

  4. Cocos creator之javascript闭包

    .什么是闭包? 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1. 作为一个函数变量的一个引用,当函数返回 ...

  5. JDK1.8源码(十一)——java.util.TreeMap类

    在前面几篇博客分别介绍了这样几种集合,基于数组实现的ArrayList 类,基于链表实现的LinkedList 类,基于散列表实现的HashMap 类,本篇博客我们来介绍另一种数据类型,基于树实现的T ...

  6. kolla-ansible安装cinder

    LVM后端 环境拓扑 节点 IP 主机名 Controller/Network/Apollo 92.0.0.11 anode Compute/Storage 92.0.0.12 bnode multi ...

  7. centos 基础设置

    centos 6 关闭防火墙 查看防火墙是否开启 service iptables status 停止防火墙 service iptables stop 禁止开机自启动防火墙 chkconfig ip ...

  8. PAT天梯赛L2-007 家庭房产

    题目链接:点击打开链接 给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数.人均房产面积及房产套数. 输入格式: 输入第一行给出一个正整数N(<=1000),随后N行,每行按下列 ...

  9. 洛谷P2486 [SDOI2011]染色

    题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例#1: 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C ...

  10. Duff and Meat(贪心)

    Duff is addicted to meat! Malek wants to keep her happy for n days. In order to be happy in i-th day ...