装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象.以下情况使用Decorator模式
1. 需要扩展一个类的功能,或给一个类添加附加职责。
2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
看了上面文字性的叙述头都晕了,下面以实例来讲解。我们都知道买奶茶可以添加各种配料,如下
这里只有了4种配料即可生成那么多种奶茶,如果我们用一个奶茶子类来存储该种奶茶的价格(价格为奶茶原价加上添加各个配料的前的和)和名称,则会派生出很多对应的子类,如果再为奶茶添加巧克力,布丁等配料,则又会添加许多子类,可以想象,每增加一种配料,对应的子类会增加很多。会导致类爆炸,也不好管理对应的子类。这里就可以使用装饰者模式来解决该问题。
1.定义被装饰者的对象接口
package com.longpo.decorator; /** * 被装饰者的对象接口 * */ public interface Drink { //奶茶名字 public String name(); //奶茶价格 public float price(); }
2.具体被装饰者的对象:奶茶
package com.longpo.decorator; /** * 具体的被装饰者对象:奶茶 * */ public class MikeTea implements Drink { @Override public String name() { return "奶茶"; } @Override public float price() { return 1f;//奶茶原价1元 } }
3.定义装饰者的父类
package com.longpo.decorator; /** *装饰者的父类 */ public abstract class Decorator implements Drink{ public Drink drink;//要装饰的对象 public Decorator(Drink drink) { this.drink=drink; } @Override public String name() { return drink.name(); } @Override public float price() { return drink.price(); } }
4.定义装饰者类:即配料
配料1:椰果类
package com.longpo.decorator; /** * 具体的装饰对象:椰果 */ public class Coconut extends Decorator{ public Coconut(Drink drink) { super(drink); } @Override public String name() { return "椰果"+super.name(); } @Override public float price() { return super.price()+0.8f;//椰果8毛 } }
配料2:珍珠类
package com.longpo.decorator; /** * 具体的装饰对象:珍珠 */ public class Pearl extends Decorator{ public Pearl(Drink drink) { super(drink); } @Override public String name() { return "珍珠"+super.name(); } @Override public float price() { return super.price()+0.5f;//珍珠5毛 } }
配料3:果条类
package com.longpo.decorator; /** * 具体的装饰对象:果条 */ public class Fruit extends Decorator{ public Fruit(Drink drink) { super(drink); } @Override public String name() { return "果条"+super.name(); } @Override public float price() { return super.price()+0.5f;//果条5毛 } }
配料4:红豆
package com.longpo.decorator; /** * 具体的装饰对象:红豆 */ public class RedBean extends Decorator{ public RedBean(Drink drink) { super(drink); } @Override public String name() { return "红豆"+super.name(); } @Override public float price() { return super.price()+1f;//红豆1元 } }
这样我们就写好了装饰者模式了,下面来测试一下装饰者模式
package com.longpo.decorator; public class DecoratorTest { public static void main(String[] args) { //首先弄杯奶茶 Drink drink=new MikeTea(); //奶茶里添加椰果 Coconut coconut=new Coconut(drink); //再添加红豆 RedBean redBean=new RedBean(coconut); System.out.println("第一杯奶茶为: "+redBean.name()+" 价格为: "+redBean.price()); //再弄杯奶茶 Drink drink1=new MikeTea(); //奶茶里添加果条 Fruit fruit=new Fruit(drink1); //再添加椰果 Coconut coconut1=new Coconut(fruit); //再添加红豆 RedBean redBean1=new RedBean(coconut1); //在添加珍珠 Pearl pearl=new Pearl(redBean1); System.out.println("-----------------------------"); System.out.println("第而杯奶茶为: "+pearl.name()+" 价格为: "+pearl.price()); } }
运行结果:
使用类装饰者模式,没添加一种配料我们主需要多添加一个配料的具体装饰者对象类就可以了。
通过上面的实际例子,已经发现了装饰者模式的好用之处了。学习了解装饰者设计模式是很有必要的,最常用的java的IO就使用了装饰者模式。
相关推荐
01.装饰者设计模式和动态代理设计模式.wmv
1. 装饰者设计模式-是什么 2. 装饰者设计模式-定义 3. 装饰者设计模式-模拟网关权限控制 4. 装饰者设计模式-测试
设计模式--装饰者模式java例子
java设计模式之装饰者模式代码
java中的装饰设计模式
设计模式—装饰者模式
Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...
设计模式—装饰者模式,介绍的非常详细,讲解透彻
设计模式 - 装饰者模式
设计模式07-组合模式、装饰模式 设计模式09-外观模式、享元模式 设计模式10-代理模式、结构型模式大复习 设计模式11-行为模式-责任链、命令模式 设计模式12-解释器模式 设计模式13-迭代器模式 设计模式14-中介者模式...
Qt设计模式之装饰者模式
c# ,设计模式,装饰者模式,星巴兹咖啡,基本上就是head first 上的例子的C#实现,根据自己的理解,作了一点点改动,可以直接运行。
设计模式主要分为三大类: 1.创建型模式:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。 2.结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。 4.行为型模式:...
该系统是一个画图程序,我们要用设计模式的思想来设计系统结构,然后实现基本图形的绘制功能。 1.1 设计模式要求 在软件的设计中请使用到三种以上设计模式。 1.2 画图基本要求 能实现基本图形的绘制功能,包括实现...
设计模式之装饰者模式,极客学院VIP课堂的课件,装饰者模式的示例
本章可以称为“给爱用继承的人一个全新的设计眼界”。我们即将再度探讨典型滥用问题。你将在本章学到如何使用对象组合的方式,做到在运行时装饰类。为什么呢?一旦你熟悉了装饰者的技巧...——《Head First 设计模式》
总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元...
设计模式的装饰者模式的例子,希望对大家有用~~~~~~~~
关于C++版本的装饰者设计模式, 供大家学习借鉴, 有问题一起讨论~