Java设计模式之装饰模式趣谈
本文由码农网 – 鲁阿皓原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!
前情提要:http://blog.csdn.net/baidu_30889437/article/details/50917814
JVM:”上次给我招的工人不错啊!”
oo程序员:”………..”
JVM:”现在来我开的博物馆生意越来越好了,原来”舞台剧”的方式已经不能满足顾客的需求了”
oo程序员:”………..”
JVM:”我决定要换一种运营模式,把每个演播厅都租出去,让那些想表演节目的对象们来租演播厅和相关器械,这样我就能坐地收钱了!”
oo程序员:”………..”
JVM:”合伙干吧?怎么样?你三我七!”
oo程序员:”………..”
JVM:”四六?”
oo程序员:”成交!先说说需求。”
JVM:”首先有不同类型的演播厅和不同的装饰品/器械,每种物品都要付一定的租金,你要做的就是一件事,把总租金(演播厅+饰品/器械)算出来。”
oo程序员:”把价格表给我!”
卡通演播厅(CartoonStudio) 100 小丑演播厅(JokerStudio) 150 超级演播厅(SuperStudio) 300 气球(Balloon) 10 灯光(Lamplight) 25 麦克风(Microphone) 20
最后还写下了这个:
public abstract class Anything_ex() { String description=" "; public String getDescription() { return description; } public abstract int cost(); }
仔细一想也对,无论是演播厅还是装饰品,都需要描述(description)和cost(价格),写一个共同的父类无可厚非。
接着写下你设计的第一个类:
class CartoonandBalloon extends Anything_ex { .... public int cost() { return 100+10; } } //带气球的卡通演播厅
第二个:
class CartoonandLamplight extends Anything_ex { ... public int cost() { return 100+25; } } //带灯光的卡通演播厅
第三个:
。。。。。
没有第三个了!这样写下去可是无穷无尽的!没办法,换个思路。
在演播厅里,无论什么装饰品都有可能出现,可以把演播厅+饰品看成一个整体,通过饰品相应的has和set来控制饰品,这样的话,设计出来的类如下:
class CartoonStudio extends Anything_ex { private boolean Balloon=false; .... //省略其他变量,这里只以气球为例 public boolean hasBalloon() { return Ballon; } public void setBallon() { Balloon=true; } .......//省略其他has/set方法 public int cost() { int cost=100; //卡通演播厅的初始价格为100 if(hasBalloon) { cost+=10; } else if(hasXXX).....//省略类推下来的代码 return cost; } }
这个看起来好多了,不用写大爆炸数量的类,虽然类写起来又臭(无数的has/set)又长(的确很长)。。。。。
但是有没有更好的方案?
答案当然是有的,不过我们必须先明确一下,上述设计的缺点。
- 1.臭
- 2.长
- 3.当饰品的租金改变的时候,必须修改所有演播厅的代码(cost部分),我们当然不想这样,我们想尽可能的少修改代码(松耦合)。
- 4.没有面对超类/接口编程。
- 5.没有将变化的部分独立开。
- 6.组合可能是更好的解决方案。
下面让我们看看。装饰者模式是如何解决上面问题的。
装饰者模式:动态的将责任加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
首先,我们先将演播厅和他的装饰者们分开,让装饰者继承另一个类:
public abstract class Decorater_ex extends Anyting_ex { public abstract String getDescription(); }
让装饰者子类重新实现getDescription()即可。
现在我们的思路是:用装饰者装饰演播厅,例如,一个带麦克风和气球的卡通演播厅,就先让气球装饰卡通演播厅,再让麦克风装饰“带气球的卡通演播厅”
先让我们分别实现这3个类:
卡通演播厅:
class CortoonStudio extends Anything_ex { public CortoonStudio() { description="CortonStudio"; } publuc int cost() { return 100; } }
麦克风:
class Microphone extends Decorater_ex { private Anything_ex studio; public Microphone(Anything_ex studio ) { this.studio=studio; } public String getDescription() { return studio.getDescription()+",Microphone"; } public int cost() { return studio.cost()+20; } }
气球:
class Balloon extends Decorater_ex { private Anything_ex studio; public Balloon(Anything_ex studio ) { this.studio=studio; } public String getDescription() { return studio.getDescription()+",Balloon"; } public int cost() { return studio.cost()+10 ; } }
代码:
Anything_ex CortoonStudio =new CortoonStudio(); //一个卡通演播厅对象 CortoonStudio=new Microphone(CortoonStudio); //拿麦克风装饰 CortoonStudio=new Balloon(CortoonStudio); //拿气球装饰 System.out.println(CortoonStudio.getDescription()+"="+CortoonStudio.cost());
输出结果:
CortonStudio,Microphone,Balloon=130
结果是正确的。
这样写很好的解决了上面的问题。
- 1.运用组合进行扩展,使当价格改变的时候,只需要修改本身的代码。
- 2.面对超类/接口编程,使饰品增加种类的时候,并不需要修改被装饰者的代码。
- 3.开放——关闭原则 :代码应该对扩展开放,对修改关闭。
缺陷:
- 1.子类繁多,影响理解代码(java I/O就是装饰者模式哦。。。)。
- 2.无法应用于需要具体类的场景。
这篇文章到此差不多结束了,作者功力尚浅,文章如有不正之处请读者指出,海涵。
Java设计模式之装饰模式趣谈的更多相关文章
- java设计模式学习笔记--浅谈设计模式
设计模式的目的 编写软件的过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战.设计模式为了让程序具有更好的 1.代码重用性(即:相同功能的代码,不用多次编写) ...
- java设计模式之装饰模式
发现设计模式的学习越来越让自己学习的东西太少了,应该多接触一些东西,多出去走一走. 装饰模式概念: 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活(大话设计模式) 在不 ...
- Java——设计模式(装饰模式_IO)
/* * 装饰设计模式: * 对一组对象的功能进行增强时,就可以使用该模式进行问题的解决; * 装饰和继承都能实现一样的特点: 就是进行功能的扩转增强. * */ public class ...
- JAVA设计模式:装饰模式
前面我们学习了代理模式: 代理模式主要使用了java的多态,干活的是被代理类,代理类主要是接活,你让我干活,好,我交给幕后的类去干,你满意就成,那怎么知道被代理类能不能干呢?同根就成,大家知根知底,你 ...
- java设计模式(装饰模式)
装饰模式实现了可以动态地为原对象扩展方法 装饰对象与被装饰的都实现了同一个接口(或抽象类) 举个例子: 工作 可以边吃东西边工作,也可以边喝东西边工作,还可以工作的时候边吃边喝 创建共同接口 Work ...
- Java设计模式(7)装饰模式(Decorator模式)
Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...
- Java设计模式学习记录-装饰模式
前言 装饰模式也是一种结构型模式,主要是目的是相对于类与类之间的继承关系来说,使用装饰模式可以降低耦合度.JDK中有不少地方都使用到了装饰模式,例如Java的各种I/O流,javax.swing包中一 ...
- Java设计模式(十三) 别人再问你设计模式,叫他看这篇文章
原创文章,转载请务注明出处 OOP三大基本特性 封装 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的属性和方法只让可信的类操作,对不可信的进行信息隐藏. 继承 继承是指这样一种能力,它可以使 ...
- Java设计模式(10)代理模式(Proxy模式)
理解并使用设计模式,能够培养我们良好的面向对象编程习惯,同时在实际应用中,可以如鱼得水,享受游刃有余的乐趣. Proxy是比较有用途的一种模式,而且变种较多,应用场合覆盖从小结构到整个系统的大结构,P ...
随机推荐
- variable-precision SWAR算法:计算Hamming Weight
variable-precision SWAR算法:计算Hamming Weight 转自我的Github 最近看书看到了一个计算Hamming Weight的算法,觉得挺巧妙的,纪录一下. Hamm ...
- 新浪微博登录接口(PHP版)
CI框架下 新浪微博登录接口完整版说明:本贴只适合CI框架.功能实现:登录接口跳转链接成功,获取用户信息(包括最重要的u_id)成功,将用户与本地平台连接起来,用户登录成功后信息的存储,本地数据库第三 ...
- PHP图片上传程序(完整版)
从PHP100上搜刮来的,功能很强大.几乎考虑到了每个细节,与大家分享!~~~ <meta http-equiv="Content-Type" content="t ...
- Java 泛型快速排序 以sdut 1196为例
oj链接:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1196 Java中,Arrays.so ...
- leetcode第八题 String to Integer (atoi) (java)
String to Integer (atoi) time=272ms accepted 需考虑各种可能出现的情况 public class Solution { public int atoi( ...
- Hibernate一对一双向关联(外键)
网站上各种搜索,都是一些清晰或者不清晰的例子,但是用下来一是确实不给力,二是完全不知道所以然. 后来终于在书中查到了就在这里记一下. 首先要说明,这里只解释双向一对一只有一个表里面有外键的情况. 就以 ...
- bzoj 1815: [Shoi2006]color 有色图 置换群
1815: [Shoi2006]color 有色图 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 136 Solved: 50[Submit][Stat ...
- 深入解析java虚拟机-jvm运行机制
转自oschina 一:JVM基础概念 JVM(Java虚拟机)一种用于计算设备的规范,可用不同的方式(软件或硬件)加以实现.编译虚拟机的指令集与编译微处理器的指令集非常类似.Java虚拟机包括一套字 ...
- ECmall错误:Call to a member function get_users_count() on a non-object
问题描述: 在后台添加了一个app报错:Call to a member function get_users_count()Fatal error: Call to a member functio ...
- "NetworkError: 500 Internal Server Error - http://develop.console.aliyun.sinopec.com/ots/ots_queryOtsList.action?state=0"
项目明明开始好好的,报的这个错,错误提示也很少,啥信息都没有,只是明白是服务器报了500,知道是服务器内部错误,但是却没法找不到问题所在.后来突然想到把下面报错的action直接在浏览器运行: htt ...