这种给对象动态地增加职责的方式称为装饰者(decorator)模式。装饰者模式能够在不改变对象自身的基础上,在程序运行期间给对象动态地添加职责。 和代理模式的区别 装饰者模式和代理模式的结构看起来非常相像,这两种模式都描述了怎样为对象提供一定程度上的间接引用,它们的实现部分都保留了对另外一个对象的引用,并且向那个对象发送请求。 代理模式和装饰者模式最重要的区别在于它们的意图和设计目的。代理模式的目的是,当直接访问本体不方便或者不符合需要时,为这个本体提供一个替代者。 装饰者模式的作用就是为对象动态加入行为。换句话说,代理模式强调一种关系(Proxy与它的实体之间的关系),这种关系在一开始就可以被确定。而装饰者模式用于一开始不能确定对象的全部功能时。 代理模式通常只有一层代理本体的引用,而装饰者模式经常会形成一条长长的装饰链。
装饰者模式(Decorator Pattern) 定义 在不改变原代码结构的情况下,动态地扩展一个对象的功能,相比继承有更灵活的实现方式。 见名知意,其就是在需要增强功能的对象上包装一层代码,达到增强功能的效果 作用 装饰者模式在对象创建好之后才动态给对象增加功能,也可以选择不增加,自由灵活。 class MyDog implements Dog { public void eat() { System.out.println("狗吃肉"); } } 下面我们使用装饰者模式给狗狗增加功能 WashHandDog(mydog); mydog = new BeatMonster(mydog); mydog.eat(); } 吃饭前洗手 狗吃肉 我的狗狗还能打怪兽 至此我们的装饰者模式就搞定了 ,是不是很简单,以后遇到增强功能的需求时可以想一想装饰者模式
装饰者模式的定义: 动态地将责任附加到对象上,若要拓展功能,装饰者提供了比继承更有弹性的替代方案对于设计模式。 总结: 先理解,搞清楚各大设计模式的好处。 再在个人/公司项目中使用设计模式,对于安卓开发工程师,接触的设计模式,可能要比后台开发人员多一点。建议不会安卓开发的适当去了解了解安卓开发。 如果想深入地了解设计模式的伙计们,建议去买一些相关书籍,书籍里面的解释往往更加生动,更加清楚。 ,继承被装饰者,与被装饰者建立联系,拥有相同的“接口”,再由具体的装饰者类与被装饰者类,组合变成一个行为。 =name; 20 } 21 22 public double getPrice() { 23 return basicPrice; 24 } 25} 4.再建立水(被装饰者
显然不科学,所以我们需要装饰者模式 装饰者模式定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。 要点: 装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为 这次我们要来将买一个带有milk和suger的一杯drink 先定义一个接口 public interface Drink } @Override public double getPrice() { return drink.getPrice(); } } 接下来就是各个装饰类了
装饰者模式 模式定义 在不改变原有对象的基础上,将功能附加到对象上 应用场景 拓展一个类的功能或者给一个类添加附加职责 优点 不改变原有对象的情况下给一个对象拓展功能 使用不同的组合实现不同的效果 符合开闭原则 Component{ @Override public void operation() { System.out.println("拍照"); } } //装饰器
介绍 定义 装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。 设计原则 多组合,少继承。 首先,将咖啡,茶等饮料定义为被装饰者,奶,糖,椰果,珍珠等定义为装饰者,当用户下单时,用户购买了一个”被装饰者”以及若干个“装饰者”,我们只需要将奶,糖,椰果,珍珠等东西装饰在被用户购买的这个被装饰者上即可 定义基类 在装饰者模式中,被装饰者和装饰者继承自同一个基类,我们定义为Component,每个Component有自己的名字以及价钱. public class Component { private 而使用装饰者模式,可以很轻松的处理各种附加要求. 特点 通过上面的例子,我们可以总结一下装饰者模式的特点。 (1)装饰者和被装饰者有相同的接口(或有相同的父类)。 优缺点 优点 扩展性好 符合开闭原则 缺点 会有许多的装饰类,导致程序复杂性提高 装饰者模式在JDK中的应用 在书中介绍完”星巴慈咖啡”的例子后,提到了在java.io包中大量使用了装饰者模式,这里对io
解决方法——装饰者模式 装饰者模式可以动态的将职责添加,不影响原来的类 装饰者模式的图示 image.png 装饰者模式的组成 1. Component 抽象组件,也叫装饰者的基类。 通过基类和多态的应用,才能实现装饰者模式 2. ConcreteComponent 具体组件,又叫被装饰对象,可以动态的给它添加职责 3. Decorator 装饰者抽象类 4. 具体的装饰者类。 可以扩展部分 5 在ConcretComponnet和ConcreteDecorator相同的方法MehtodeA 举例 IO的装饰者模式 image.png 使用 如下就动态的给fileInputStream
装饰器模式 动态地给一个对象添加一些额外的职责,装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。装饰器模式的本质就是动态组合。 装饰器模式意图和结构 装饰者模式提供了一种给类增加功能的方法,它通过动态组合可以给原有的代码新增加新的代码,达到修改现有代码的目的,因此我们可以用在修复bug上。 装饰者模式主要有Component、ConcreteComponent、Decorator和ConcreteDecorator组成。 具体组件角色(ConcreteComponent) :被装饰者,定义一个将要被装饰增加功能的类。可以给这个类的对象添加一些职责。 ConcreteDecoratorA(c1); decoratorA.operation(); } } 总结 使用装饰者模式应注意以下几点: 接口的一致性:装饰器对象的接口必须与它所装饰的Component
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比生成子类更为灵活。——《设计模式:可复用面向对象软件的基础》 装饰者模式是一种对象结构型模式。 图示 装饰者模式(Decorator)结构图 代码示例 装饰者模式(Decorator)代码示例类图 这是一个关于相亲的故事。 装饰者模式进阶 透明与半透明的装饰者模式 透明的装饰者模式:要求客户端完全针对抽象编程(依赖倒置原则),装饰者模式的透明型要求客户端程序不应该声明具体构件类型和具体装饰者类型,而应该全部声明为抽象构件类型 这里的装饰者模式大多都是半透明的,具体装饰者提供了比抽象构件多的方法,客户端可以使用这些方法。 装饰者模式的简化 装饰者有3种简化模式: 第一种情况,只有一个具体装饰者,这样就不需要抽象装饰者,具体装饰者直接继承抽象构件就可以了。
在23种设计模式中,装饰者模式在游戏开发的过程中,使用的很是频繁。因为这个设计模式,把所有的业务的逻辑封装的对应的实体类中,从而为主流程减负了。 首先看下一个应用场景 装饰者模式的应用 我们都知道有一款经典游戏90坦克,这个游戏中,玩家坦克来操作坦克打击AI敌人,在没打死一个红色坦克就会掉下来一个装备,这个装备可以提升移动速度,增加攻击力。 装饰者实现流程图 ? 装饰者实现逻辑 经过上面的分析,我们可以使用代码来表示我们的设计。 在java 中,IO的实现逻辑就是装饰者模式 ,首先看下IO的逻辑类图: ? 知道了装饰者模式,我们就可以更好的使用IO的类。
[设计模式] 装饰者模式 ? 手机用户请 横屏获取最佳阅读体验, REFERENCES中是本文参考的链接,如需要链接和更多资源,可以关注其他博客发布地址。 sinat_28690417 简书 https://www.jianshu.com/u/3032cc862300 个人博客 https://yiyuery.github.io/NoteBooks/ 装饰者模式 首先我们来分析下装饰者模式中有哪些角色: 装饰器:用于扩展被装饰者行为和特征 被装饰者:设计主体,一切的行为包装都为了丰富被装饰者的行为或是能力。 场景分析 朋友开了家畅饮吧,可以喝到不同种类的饮料。 ,我们可以发现装饰模式是装饰器层层嵌套的一种设计模式,设计的主体就是被装饰者。 装饰者模式,动态地将责任附加到对象上,想要扩展功能,装饰者提供有别于继承的另一种选择 这种循环嵌套包装类的方式也可以理解为委托的方式,通过组合和委托,可以在运行时动态的添加新的行为 装饰者模式意味着有一群装饰器
装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。一言以蔽之 —— 动态扩展类的行为。 @Override public double cost() { return beverage.cost() + 0.20; } } 5、测试 测试类能帮你对装饰者模式有更清晰的认识 特点: 1、装饰者和被装饰者对象有相同的超类型。 2、你可以用一个或多个装饰者包装一个对象。 3、装饰者可以在所委托的被装饰者行为之前或之后,加上自己的行为,以达到特定的目的。 4、对象可以在任何时候被装饰,所以你可以在运行时动态地、不限量的用你喜欢的装饰者来装饰对象。 优点:装饰者模式的设计具有弹性,可以应对改变,可以接受新的功能来应对改变的需求。 缺点:如果每个地方都采用开放-封闭原则是一种浪费,也没必要,还会导致代码变得复杂且难以理解。比如会产生很多的小类。
---- 重点来了 装饰者设计模式 装饰者模式定义 装饰者模式:动态的将新功能附加到对象上。 在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp) 原理图: 说明: 装饰者模式原理 装饰者模式就像是打包快递 主体 比如:衣服 、水果 属于被装饰者 Component 包装 好了装饰者设计模式的理论知识差不多了,我们来解决一下一开始的咖啡问题吧。 接下来给大家讲一讲装饰者模式在JDK源码中的应用吧。 不知道大家是否熟悉Java的IO结构,里面的FileInputStream就是一个装饰者。 in; 即含被装饰者 分析得出在jdk 的io体系中,就是使用装饰者模式 ---- okay 到这里关于装饰者设计模式的应用案例以及源码分析讲到这里就已经结束了,不知看完这篇文章的你是否有所收获。
装饰者模式可以做到在不修改任何底层代码的情况下,给对象增加的新的方法。 首先,我们通过对一个现实问题的模拟分析,了解什么是装饰者模式以及装饰者模式的作用。 ---- 问题提出 咖啡店在街头随处可见。 这样就是实现的装饰者模式解决这个问题的思路。 下面我们看一下装饰者模式的定义,以及代码实现的基本思路 定义装饰者模式 装饰者模式动态的将责任附加到对象上。 这符合我们之前提到的设计原则多用组合,少用继承 实现装饰者模式 如果看到这里还是不太清楚,也没关系,接下来我们将具体实现代码,对装饰者模式有一个直观根本的了解。 装饰者模式用到的技术主要有两种就是组合和委托,这帮助我们动态的在运行时加上新的行为。 装饰者模式意味着一群装饰者类,这些类用来包装装饰者。 装饰者和被装饰者类实际上具有相同类型的。 装饰者可以在被装饰者的行为前面或后面加上自己的行为,甚至完全覆盖。 但装饰者模式的使用会导致出现很多小对象,就是装饰者对象,过度使用也会使程序变得复杂。
装饰者模式又叫包装模式,他能够以透明的方式扩展对象的功能,是继承方式的另外一种替代方案。 和代理模式很相似,但在对被装饰的对象的控制程度是不同的;装饰者模式是对对象功能的加强,而代理模式是对对象施加控制,并不提供对对象本身功能的加强。 首先看下装饰者模式的类图 ? 说明下: Component,给出一个抽象接口,规范实现类的一些方法; ConcreteComponent:具体的一个组件,实现了接口方法; Decorator:抽象的装饰者,对接口的一个引用,在 method 方法里面使用这个引用完成任务;(代理模式需要实例化) ConcreteDecorator:具体的装饰者,对抽象装饰者的抽象部分进行实现 下面给出实现代码 抽象组件接口: public interface 装饰者模式可以演变一种更加直观的,就是没有 Component 抽象组件,抽象装饰者直接继承某个类,对这个类进行装饰。 还可以把抽象装饰与具体装饰合二为一,对功能简单的可以这样优化处理。
装饰者模式 介绍 角色 示例代码 星巴克咖啡的例子 方案一 方案二 :将调料内置到Drink类中 方案三:装饰者模式 代码演示 装饰者模式的简化 透明性的要求 半透明的装饰模式 装饰模式的优点 装饰模式的缺点 装饰模式注意事项 适用场景 设计模式在JAVA I/O库中的应用 透明和半透明的装饰模式的区别 参考文章 ---- 介绍 装饰者模式(Decorator Pattern):动态地给一个对象增加一些额外的职责 在装饰者模式中,为了让系统具有更好的灵活性和可扩展性,我们通常会定义一个抽象装饰类,而将具体的装饰类作为它的子类 装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。 好啦,装饰者可以非常完美的解决以上的所有问题,让我们有一个设计非常nice的咖啡馆。 ---- 参考文章 设计模式 | 装饰者模式及典型应用 齐天大圣的故事 星巴兹咖啡的故事 ----
有些问题 : 1)增删调料种类 2)添加多份问题 装饰者模式就像打包一个快递 1)主体:陶瓷、衣服 2)包装:报纸填充、塑料泡沫、纸板、木板 装饰者模式: ? 装饰者模式: 动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性。 用装饰者模式重新设计的方案 ? 装饰者模式下的订单:2份巧克力+一份牛奶的LongBlack ? order.cost()); System.out.println("order2 desc:"+order.getDescription()); } Java里装饰者介绍
装饰者模式: 动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。 新的包装类肯定要持有原有基类的句柄,然后覆盖超类中的方法。 Java语言的I/O流系统就是装饰者模式的非常典型的代表。 示例:星巴兹咖啡订单系统。星巴兹提供多种口味咖啡并且提供向咖啡中添加各种调料的服务。 装饰者和被装饰者有相同的超类型 既然有相同的超类型,你可以在任何需要原始对象(被包装的)的场合,用装饰过的对象代替它。 装饰者可以在所委托被装饰者的行为之前/之后,加上自己的行为,以打到特定的目的。 装饰者模式也可以让我们扩展行为。 装饰者模式意味着一群装饰者类,这些类用来包裹具体组件。 装饰者类反映出被装饰的组件类型(其实他们具有相同的类型,都经过接口或继承实现)。 装饰者可在被装饰者的行为前面/后面加上自己的行为甚至整个取代掉,而达到特定的目的。
package com.shi.design.director; /** * 装饰者模式 * @author shiye * */ public abstract class Drink { CofferSun3() { setDesc(" 第三种咖啡 "); setPrice(30.0f); } } package com.shi.design.director; /** * 装饰者 void setDrink(Drink drink) { this.drink = drink; } } package com.shi.design.director; /** * 巧克力 装饰者 setDrink(drink); setDesc(" 牛奶 "); setPrice(3.0f); } } package com.shi.design.director; /** * 豆浆装饰者 setDrink(drink); setDesc(" 豆浆 "); setPrice(1.5f); } } package com.shi.design.director; /** * 装饰者模式测试
装饰者模式是一种结构型设计模式,它允许在不改变对象结构的情况下,动态地添加行为或修改现有行为。在该模式中,通常将核心对象称为“组件”,并且将新增的行为称为“装饰者”。 使用装饰者模式的好处是可以将对象的功能拆分成多个小的、单一的职责,从而使每个职责都可以进行独立的扩展和修改,而不会对其他职责造成影响。 此外,装饰者模式还可以避免使用继承带来的类爆炸问题,使得代码更加灵活和易于维护。假设我们有一个咖啡店,我们需要在不改变原有咖啡的基础上,为顾客提供添加调料的服务。 @Override public double getCost() { return coffee.getCost() + 0.3; }}最后,我们可以通过如下方式来使用装饰者模式 输出结果如下:Simple Coffee $1.0Simple Coffee, Milk $1.5Simple Coffee, Milk, Sugar $1.8可以看到,我们通过装饰者模式,成功地为咖啡店提供了添加调料的服务