JAVA装饰者模式(从现实生活角度理解代码原理)
装饰者模式可以动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
该模式的适用环境为:
(1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
(2)处理那些可以撤消的职责。
(3)当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
实现该模式的关键步骤:
(1)Component(被装饰对象基类):定义对象的接口,可以给这些对象动态增加职责;
(2)ConcreteComponent(具体被装饰对象):定义具体的对象,Decorator可以给它增加额外的职责;
(3)Decorator(装饰者抽象类):维护指向Component实例的引用,定义与Component一致的接口(也就是要继承或实现被装饰对象基类);
(4)ConcreteDecorator(具体装饰者):具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责;
这样讲大家可能有些不好理解,那我们还是老规矩:
入冬以后天气越来越冷了,下班之后,做为资深吃货,约上二三好友痛快的来场火锅盛宴再爽不过了。说到火锅,不得不提在成都吃过的大龙燚火锅,各种锅底,配菜应有尽有,但我最喜欢的还是大龙燚火锅原味锅底、麻辣牛肉、大刀毛肚、天味香肠、砣砣牛肉、麻辣排骨等,想想都流口水啊。
说道这大家结合装饰者的实现步骤,应该有点感觉了吧,上文提到的锅底,其实就是被装饰对象的基类,配料其实就是装饰者抽象类,大龙燚火锅原味锅底这些具体的锅底也就是具体的被装饰对象了,麻辣牛肉、大刀毛肚、天味香肠、砣砣牛肉、麻辣排骨这些装饰锅底用的各种配菜也就是具体的装饰对象。说道这,大家应该都豁然开朗了吧,下面我们开始具体的代码实现:
第一步:定义被装饰对象基类(可以是抽象类也可以是接口)
public interface GuoDi {
public float cost();//锅底当然要有价钱啦
public String name();//名字也得有哦
}
第二步:定义具体被装饰对象(也就是各种锅底,这里定义两种)
public class YuanYang implements GuoDi {
@Override
public float cost() {
return 48.0f;
}
@Override
public String name() {
return "鸳鸯锅底";
}
}
public class DaLongYan implements GuoDi{
@Override
public float cost() {
return 59.0f;
}
@Override
public String name() {
return "大龙燚火锅原味锅底";
}
}
第三步:定义装饰者抽象类
public abstract class PeiCai implements GuoDi {
private GuoDi guodi;
public FoodDecorator(GuoDi guodi) {
super();
this.guodi = guodi;
}
@Override
public float cost() {
return guodi.cost();
}
@Override
public String name() {
return guodi.name();
}
}
第四步:定义具体的装饰者对象
public class MaLaNiuRou extends PeiCai {
public MaLaNiuRou(GuoDi guodi) {
super(guodi);
}
@Override
public float cost() {
return super.cost()+46f;
}
@Override
public String name() {
return super.name()+"+麻辣牛肉";
}
}
public class MaoDu extends PeiCai { public MaoDu(GuoDi guodi) {
super(guodi);
}
@Override
public float cost() {
return super.cost()+30f;
}
@Override
public String name() {
return super.name()+"+大刀毛肚";
}
}
测试类:
public class Test {
public static void main(String[] args) {
GuoDi guodi = new DaLongYan ();//点个大龙燚火锅原味锅底
MaLaNiuRou y = new MaLaNiuRou(guodi);//来个麻辣牛肉
MaoDu x = new MaoDu(y);//在麻辣牛肉的基础上再来个大刀毛肚
System.out.println("一共点了"+x.name()+",共消费"+s.cost());
}
}
输出结果:
一共点了大龙燚火锅原味锅底+麻辣牛肉+大刀毛肚,共消费135
不知道大家这顿吃的满意不,不行的话,咱去成都来顿真正的装饰者设计模式,看我不把我的大龙燚火锅原味锅底装饰的让你走不动道。
JAVA装饰者模式(从现实生活角度理解代码原理)的更多相关文章
- JAVA静态代理模式(从现实生活角度理解代码原理)
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问. 代理模式说白了就是"真实对象"的代表,在访问对象时引入一定程度的间接性,因为这种间接性可以附加多种用途. 在 ...
- JAVA模板方法设计模式(从现实生活角度理解代码原理)
概述: 定义一个功能的框架(骨架),一部分功能是确定的,一部分功能是不确定的,先把确定的部分实现,把不确定的部分延迟到子类中实现. 实现该模式的关键步骤: 第一步:抽象类,实现模板方法,定义功能(确定 ...
- JAVA简单工厂模式(从现实生活角度理解代码原理)
简单工厂模式(Simple Factory),说他简单是因为我们可以将此模式比作一个简单的民间作坊,他们只有固定的生产线生产固定的产品.也可以称他为静态工厂设计模式,类似于之前提到过静态代理设计模式, ...
- JAVA动态代理模式(从现实生活角度理解代码原理)
所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...
- JAVA适配器模式(从现实生活角度理解代码原理)
说道JAVA中的适配器模式,不得不引用该设计模式的固定表述"适配器模式(Adapter ):将一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类 ...
- java装饰者模式理解
java 装饰者模式其实就是扩展子类的功能,和继承是一个性质. 但继承是在编译时就固定扩展了父类的一些功能,而装饰者模式是在运行过程中动态绑定对象,实现一个子类可以随时扩展功能. 将方法排列组合,也可 ...
- Java 装饰器模式详解
转载请注明出处:http://blog.csdn.net/zhaoyanjun6/article/details/56488020 前言 在上面的几篇文章中,着重介绍了Java 中常见的 IO 相关知 ...
- java 装饰者模式与继承的区别
装饰者模式目标 把许多要实现的功能,加载在子类上,类的继承,显得很臃肿,装饰着模式是在不改变原有类文件和使用继承的情况下,通过创建一个包装对象动态地扩展一个对象的功能,相比生成子类更为灵活 装饰者模式 ...
- JAVA装饰器模式
Java程序员们应该对java.io对不会陌生,因为java.io包采用了装饰器模式. 一.定义: Decorator装饰器,顾名思义,就是动态地给一个对象添加一些额外的职责,就好比为房子进行装修一样 ...
随机推荐
- 《Web 前端面试指南》1、JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- H5坦克大战之【建造敌人的坦克】
公司这几天在准备新版本的上线,今天才忙里偷闲来写这篇博客.接着上一篇的"H5坦克大战之[玩家控制坦克移动2]"(http://www.cnblogs.com/zhouhuan/ ...
- 一个粗心的Bug,JSON格式不规范导致AJAX错误
一.事件回放 今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里. 当时正在联调一个项目,由于后端没有提供数据接口,于是我直接本地建立了一个 json ...
- TODO:GitHub创建组织的步骤
TODO:GitHub创建组织的步骤 使用GitHub进行团队合作,写这个步骤主要作用是为了OneTODO作为一个团队组织进行代码的分享,让更多人来参与. 使用帐号.密码登录GitHub 2.右上角加 ...
- RestTemplate发送请求并携带header信息
1.使用restTemplate的postForObject方法 注:目前没有发现发送携带header信息的getForObject方法. HttpHeaders headers = new Http ...
- Yeoman 官网教学案例:使用 Yeoman 构建 WebApp
STEP 1:设置开发环境 与yeoman的所有交互都是通过命令行.Mac系统使用terminal.app,Linux系统使用shell,windows系统可以使用cmder/PowerShell/c ...
- [C#] 走进 LINQ 的世界
走进 LINQ 的世界 序 在此之前曾发表过三篇关于 LINQ 的随笔: 进阶:<LINQ 标准查询操作概述>(强烈推荐) 技巧:<Linq To Objects - 如何操作字符串 ...
- 步入angularjs directive(指令)--准备工作熟悉hasOwnProperty
在讲解directive之前,先做一下准备工作,为何要这样呢? 因为我们不是简单的说说directive怎么用,还要知道为什么这么用!(今天我们先磨磨刀!). 首先我们讲讲js 基础的知识--hasO ...
- QT内省机制、自定义Model、数据库
本文将介绍自定义Model过程中数据库数据源的获取方法,我使用过以下三种方式获取数据库数据源: 创建 存储对应数据库所有字段的 结构体,将结构体置于容器中返回,然后根据索引值(QModelIndex) ...
- sqlServer去除字符串空格
说起去除字符串首尾空格大家肯定第一个想到trim()函数,不过在sqlserver中是没有这个函数的,却而代之的是ltrim()和rtrim()两个函数.看到名字所有人都 知道做什么用的了,ltrim ...