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到目前已经写了九个设计模 ...
随机推荐
- 时间同步方法及几个可用的NTP服务器地址
大家都知道计算机电脑的时间是由一块电池供电保持的,而且准确度比较差经常出现走时不准的时候.通过互联网络上发布的一些公用网络时间服务器NTP server,就可以实现自动.定期的同步本机标准时间. 依靠 ...
- 交作业啊,python爬取58的页面
第一次写博文,好紧张啊,写这么烂怎么给别人看啊先做下总结: 刚开始学习python,自我感觉python写起来确实很方便,各种库,各种语法糖,不过刚接触,一下子记不下来这么多东西,总感觉乱乱的,用的多 ...
- 一个全局变量引起的DLL崩溃
参考我发的帖子: http://bbs.csdn.net/topics/390737064?page=1#post-397000946 现象是exe程序在加载dll的时候崩溃了,莫名其妙的崩溃了.换其 ...
- 基于Prism.Windows的UWP开发备忘
以前做UWP开发都是使用MvvmLight,主要是简单易上手,同时也写了很多MvvmLight的开发系列文章: UWP开发必备以及常用知识点总结 UWP开发之Mvvmlight实践九:基于MVVM的项 ...
- webrtc学习笔记1(建立连接基本流程)
最近在做一个基于webrtc的视频软件,以下是自己对于上层建立通话连接流程的基本理解,记录于此. 假设A和B要建立视频通话,A为房间创建端,B为加入房间端: 1.A通过http登录.获取其他服务器地址 ...
- GTK简单了解记录
GTK+http://zh.wikipedia.org/wiki/GTK%2B#.E5.9B.BE.E5.BD.A2.E6.97.A0.E5.85.B3.E4.BB.A3.E7.A0.81 GTK+最 ...
- 什么是体数据可视化(Volume data visualization)?及体绘制的各种算法和技术的特点?
该文对体数据进行综述,并介绍了体数据的各种算法和技术的特点. 前言 由于3D数据采集领域的高速发展,以及在具有交互式帧率的现代化工作站上执行高级可视化的可能性,体数据的重要性将继续迅速增长. 数据集可 ...
- 再议Unity优化
0x00 前言 在很长一段时间里,Unity项目的开发者的优化指南上基本都会有一条关于使用GetCompnent方法获取组件的条目(例如14年我的这篇博客<深入浅出聊Unity3D项目优化:从D ...
- 产品经理学Python:条件控制
条件控制其实就是if...else...(如果...条件是成立的,就做...:反之,就做...)的使用,其基本结构是: 具体看下面这个例子: def account_login(): # 定义函数 p ...
- dp
1. 将原问题分解为子问题 2. 确定状态 3. 确定一些初始状态(边界状态)的值 4. 确定状态转移方程 1) 问题具有最优子结构性质.如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具 ...