Java中设计模式之装饰者模式-3
装饰者模式:
动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。
装饰者核心:实现功能组合
继承与组合区别:
继承
继承是给一个类添加行为的比较有效的途径。通过使用继承,可以使得子类在拥有自身方法的同时,还可以拥有父类的方法。但是使用继承是静态的,在编译的时候就已经决定了子类的行为,我们不便于控制增加行为的方式和时机。
组合
组合即将一个对象嵌入到另一个对象中,由另一个对象来决定是否引用该对象来扩展自己的行为。这是一种动态的方式,我们可以在应用程序中动态的控制。
与继承相比,组合关系的优势就在于不会破坏类的封装性,且具有较好的松耦合性,可以使系统更加容易维护。但是它的缺点就在于要创建比继承更多的对象。
装饰者模式优点
一句话:在原有的基础上 ,增加功能 ,提高效率
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的更多相关文章
- Java 的设计模式之一装饰者模式
刚开始接触装饰者的设计模式,感觉挺难理解的,不够后来花了一个晚上的时间,终于有头绪了 装饰者设计模式:如果想对已经存在的对象进行装饰,那么就定义一个类,在类中对已经有的对象进行功能的增强或添加另外的行 ...
- Java设计模式12:装饰器模式
装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...
- JAVA设计模式之【装饰者模式】
JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...
- java进阶系列之装饰器模式
1.介绍 装饰器模式顾名思义就是装饰某个对象的,是一种结构型模式.装饰器模式允许向一个现有对象添加新的功能,同时不改变其结构,用户可以随意的扩展原有的对象.它是作为现有的类的一个包装.装饰器模式一方面 ...
- Java中代理和装饰者模式的区别
装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案: 代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用: 装饰模式为所装饰的对象增强功能:代理模式对代理的对 ...
- [转载]Java中继承、装饰者模式和代理模式的区别
[转载]Java中继承.装饰者模式和代理模式的区别 这是我在学Java Web时穿插学习Java设计模式的笔记 我就不转载原文了,直接指路好了: 装饰者模式和继承的区别: https://blog.c ...
- Java进阶篇设计模式之五-----外观模式和装饰器模式
前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...
- Java设计模式之五 ----- 外观模式和装饰器模式
前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...
- 涉及模式之 装饰器模式详解(与IO不解的情缘)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. LZ到目前已经写了九个设计模 ...
随机推荐
- 如何禁止火狐onblur时alert()产生类似选中的拖蓝效果
输入框中onblur 然后alert();会产生 复制 选中的效果的效果( 拖蓝) onblur="aa()"function aa(){ alert("--" ...
- python入门编程之基础
Python, 是一种面向对象.解释型计算机程序设计语言.Python语法简洁清晰,特色之一是强制用空白符作为语句缩进.Python的设计哲学是"优雅"."明确" ...
- Android学习探索之运用MVP设计模式实现项目解耦
前言: 一直致力于提高开发效率降低项目耦合,今天想抽空学习一下MVP架构设计模式,学习一下如何运用到项目中. MVP架构设计模式 MVP模式是一种架构设计模式,也是一种经典的界面模式.MVP中的M代表 ...
- Linux - 进程间通信 - 信号量
一.概念 简单来讲,信号量是一个用来描述临界资源的资源个数的计数器. 信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件.外部设备等)来实现进程间通信, 他本身 ...
- OpenGL 的空间变换(上):矩阵在空间几何中的应用
在使用 OpenGL 的应用程序中,当我们指定了模型的顶点后,顶点依次会变换到不同的 OpenGL 空间中,最后才会被显示到屏幕上.在变换的过程中,通过使用矩阵,我们更高效地来完成这些变换工作. 本篇 ...
- Jmeter如何将上一个请求的结果作为下一个请求的参数——使用正则表达式提取器
首先在线程组下添加两个HTTP请求, 添加好两个HTTP请求后,在每个HTTP请求下添加一个查看结果数 在第一个HTTP请求下添加正则表达式提取器 在第一个HTTP请求添加好IP地址,路径,端口号,协 ...
- 创建,删除DOM
需求说明: 1.上传图片,有删除功能,可上传5张,至少上传一张 html代码如下 <div class="imgUpBox"> <div class=" ...
- bzoj4514 [Sdoi2016]数字配对
Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对 ...
- web安全—浏览器的进制
浏览器的进制 字符的ascii码值可以转化为进制形式.可以用来绕过XSS filter. HTML属性值中的进制使用 .十进制使用a 表示,&#作为前缀,;作为后缀,后缀也可以没有. 如果要使 ...
- 利刃 MVVMLight 8:DispatchHelper在多线程和调度中的使用
在应用程序中,线程可以被看做是应用程序的一个较小的执行单位.每个应用程序都至少拥有一个线程,我们称为主线程,这是在启动时调用应用程序的主方法时由操作系统分配启动的线程. 当调用和操作主线程的时候,该操 ...