装饰者模式:

动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。

装饰者核心:实现功能组合

继承与组合区别:

继承

继承是给一个类添加行为的比较有效的途径。通过使用继承,可以使得子类在拥有自身方法的同时,还可以拥有父类的方法。但是使用继承是静态的,在编译的时候就已经决定了子类的行为,我们不便于控制增加行为的方式和时机。

组合

组合即将一个对象嵌入到另一个对象中,由另一个对象来决定是否引用该对象来扩展自己的行为。这是一种动态的方式,我们可以在应用程序中动态的控制。

与继承相比,组合关系的优势就在于不会破坏类的封装性,且具有较好的松耦合性,可以使系统更加容易维护。但是它的缺点就在于要创建比继承更多的对象。

装饰者模式优点

一句话:在原有的基础上 ,增加功能 ,提高效率

1、装饰者模式可以提供比继承更多的灵活性

2、可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。

3、通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。

4、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

装饰者模式缺点

一句话:繁琐

1、会产生很多的小对象,增加了系统的复杂性

2、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

装饰者应用场景

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

2、需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。

个人理解:

装饰者模式是指在继承父类后,重写父类方法时,不改变父类中该方法的原有功能,只是在该功能基础上添加自己想要扩充的功能。

一句话:父类原有功能不变,子类再添加其他功能

简单实例:

父类

package 设计模式之装饰者模式;

public class Father {
public void run(){
System.out.println("跑步...");
}
}

子类:

在子类中重写run方法时,不改变父类的原有功能,并根据需要添加自己的功能。这里的装饰并不复杂,不存在多层装饰,所以在子类中创建一个父类属性是多余的,但在多层装饰中,这是必要的。

package 设计模式之装饰者模式;

public class Son extends Father {
Father father; public Son(Father father) {
super();
this.father = father;
} @Override
public void run() {
System.out.println("欣赏周围的美景...");
father.run();
System.out.println("听歌...");
}
}

测试类:

package 设计模式之装饰者模式;

public class Test {
public static void main(String[] args){
Father father=new Father();
father.run();
System.out.println("son:");
Son son = new Son(father);
son.run();
}
}

结果:

多层装饰实例

借鉴实例,来自http://www.cnblogs.com/xinye/p/3910149.html

逻辑分析图:

1.装饰者基类(被操作的对象)

package com.xinye.test.decoration;
/**
* 食物基类
* @author xinye
*
*/
public abstract class Food { protected String desc; public abstract String getDesc();
}

2.被操作对象具体类

鸡肉

package com.xinye.test.decoration;
/**
* 鸡肉
* @author xinye
*
*/
public class Chicken extends Food {
public Chicken(){
desc = "鸡肉";
}
@Override
public String getDesc() {
return desc;
} }

鸭肉

package com.xinye.test.decoration;
/**
* 鸭肉
* @author xinye
*
*/
public class Duck extends Food {
public Duck(){
desc = "鸭肉";
}
@Override
public String getDesc() {
return desc;
} }

3.装饰者基类(操作类,对对象实现什么操作)

package com.xinye.test.decoration;
/**
*
* @author xinye
*
*/
public abstract class FoodDecoration extends Food { @Override
public abstract String getDesc(); }

4.具体操作类

蒸-装饰者

package com.xinye.test.decoration;
/**
* 蒸食物
* @author xinye
*
*/
public class SteamedFood extends FoodDecoration { private Food food; public SteamedFood(Food f){
this.food = f;
} @Override
public String getDesc() {
return getDecoration() + food.getDesc();
} private String getDecoration(){
return "蒸";
}
}

烤-装饰者

package com.xinye.test.decoration;
/**
* 烤食物
* @author xinye
*
*/
public class RoastFood extends FoodDecoration { private Food food; public RoastFood(Food f){
this.food = f;
} @Override
public String getDesc() {
return getDecoration() + food.getDesc();
} private String getDecoration(){
return "烤";
}
}

5.测试类(客户端)

package com.xinye.test.decoration;
/**
* 客户端
* @author xinye
*
*/
public class Client {
public static void main(String[] args) {
// 测试单纯的食物
Food f1 = new Chicken();
System.out.println(f1.getDesc()); System.out.println("----------------------");
// 测试单重修饰的食物
RoastFood rf = new RoastFood(f1);
System.out.println(rf.getDesc()); System.out.println("----------------------");
// 测试多重修饰的食物
SteamedFood sf = new SteamedFood(rf);
System.out.println(sf.getDesc());
}
}

执行结果:

鸡肉

烤鸡肉

蒸烤鸡肉

Java中设计模式之装饰者模式-3的更多相关文章

  1. Java 的设计模式之一装饰者模式

    刚开始接触装饰者的设计模式,感觉挺难理解的,不够后来花了一个晚上的时间,终于有头绪了 装饰者设计模式:如果想对已经存在的对象进行装饰,那么就定义一个类,在类中对已经有的对象进行功能的增强或添加另外的行 ...

  2. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  3. JAVA设计模式之【装饰者模式】

    JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...

  4. java进阶系列之装饰器模式

    1.介绍 装饰器模式顾名思义就是装饰某个对象的,是一种结构型模式.装饰器模式允许向一个现有对象添加新的功能,同时不改变其结构,用户可以随意的扩展原有的对象.它是作为现有的类的一个包装.装饰器模式一方面 ...

  5. Java中代理和装饰者模式的区别

    装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案: 代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用: 装饰模式为所装饰的对象增强功能:代理模式对代理的对 ...

  6. [转载]Java中继承、装饰者模式和代理模式的区别

    [转载]Java中继承.装饰者模式和代理模式的区别 这是我在学Java Web时穿插学习Java设计模式的笔记 我就不转载原文了,直接指路好了: 装饰者模式和继承的区别: https://blog.c ...

  7. Java进阶篇设计模式之五-----外观模式和装饰器模式

    前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...

  8. Java设计模式之五 ----- 外观模式和装饰器模式

    前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...

  9. 涉及模式之 装饰器模式详解(与IO不解的情缘)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. LZ到目前已经写了九个设计模 ...

随机推荐

  1. Java: 隐性赋值(Implicit Assignment)

    初学 Java 时,我总是记不住如何区别 i++ 和 ++i.在<算法(第四版)>一书中第16页,作者提到: ** ++i ** is the same as i = i+1, and h ...

  2. linux c socket 并发 服务端

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types. ...

  3. JAVA压缩图片 服务器端压缩图片 原创

    @RequestMapping(value = "/uploadImage", method = RequestMethod.POST) @ResponseBody public ...

  4. nginx源码分析——http模块

         源码:nginx 1.12.0      一.nginx http模块简介           由于nginx的性能优势,现在已经有越来越多的单位.个人采用nginx或者openresty. ...

  5. hdu2767强连通加缩点

    https://vjudge.net/contest/156688#problem/B 题目说了一大堆,前面的没有用,就是让你判断要加几条边才能强连通,用到缩点的知识 二重循环,判断邻接表下一个点是不 ...

  6. Java IO最详解

    初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂.而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见 ...

  7. linux 内核的rt_mutex 锁操作实现的临界区

    rt_mutex 定义的锁规则: 以偶对齐的task_struct指针为上锁标记, 偶对齐的指针地址最低位用以标记是否有waiters. rt_mutex的trylock,lock,以及unlock都 ...

  8. 腾讯ISUX网页前端代码分析

    看了一下腾讯ISUX网页,无论是pc端还是移动端,展示都挺好看的,先对其代码进行分析如下: 1,先看前三行代码 <!DOCTYPE html> <!-- 腾讯 ISUX 是腾讯集团核 ...

  9. Echarts环形进度使用 【1 简单的使用示例】

    使用中说明几点属性:  hoverAnimation:false,//此处查了好久属性//控制鼠标放置在环上时候的交互//这里一个简单的示例使用Echarts 环形图使用方式//常用于统计完成进度等等 ...

  10. 禁止LISTCTRL表头拖动

    禁止ListCtrl表头拖动(Prevent CListCtrl column resizing) /*The header control in the ListView control sends ...