Java学习笔记——设计模式之三.装饰模式
函数应该做一件事,做好这件事,只做这一件事。
——Clean Code

装饰模式,上代码:
先定义零件类:
package cn.no3.decorator.template;
public abstract class Component {
public abstract void operation();
}
再定义具体零件类(即被装饰类)继承零件类:
package cn.no3.decorator.template;
public class ConcreteComponent extends Component{
@Override
public void operation() {
// TODO Auto-generated method stub
System.out.println("对一个Object进行装饰:");
}
}
然后定义装饰类,继承零件类:
package cn.no3.decorator.template;
public class Decorator extends Component {
protected Component component;
public void setComponent(Component component) {
this.component = component;
}
@Override
public void operation() {
//调用的是传入component的operation方法
if (component != null) {
component.operation();
}
}
}
定义装饰类的子类:
package cn.no3.decorator.template;
public class ConcreteDecoratorA extends Decorator {
private String addedField;
@Override
public void operation() {
// TODO Auto-generated method stub
super.operation();//第一行调用super,则从前往后包装.反之则从后往前包装
addedField = "新的装饰物A";
System.out.println("装饰了:"+addedField);
}
}
public class ConcreteDecoratorB extends Decorator {
@Override
public void operation() {
// TODO Auto-generated method stub
super.operation();
AddedBehavior();
}
private void AddedBehavior() {
// TODO Auto-generated method stub
System.out.println("完成装饰,最后照个相");
}
}
测试类测试:
package cn.no3.decorator.template;
public class _Test {
public static void main(String[] args) {
//新建装饰对象
ConcreteComponent concreteComponent = new ConcreteComponent();
ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA();
ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB();
//逐层包装
//如果注掉下句,还是先调用A的super,发现没传component,于是A的super什么都不做
concreteDecoratorA.setComponent(concreteComponent);//A先调用cC,cC方法不再调用super.
concreteDecoratorB.setComponent(concreteDecoratorA);//B先调用A
//输出最终结果
concreteDecoratorB.operation();
}
}
把这个例子中的Component类换成接口也是一样的:
举个例子:
需求:
定义一个角色,让他实现IWearable接口,
再定义装备实现IWearable接口
人物装备装备.
上代码:
package cn.no3.decorator.instance;
public abstract interface IWearable {
public abstract void operation();
}
package cn.no3.decorator.instance;
public class Clothes implements IWearable {
protected IWearable component;
public void setComponent(IWearable component) {
this.component = component;
}
@Override
public void operation() {
if (component != null) {
component.operation();
}
}
}
package cn.no3.decorator.instance; //即使只有一双鞋也要定义父类,否则无法通过对象的super.operation对装饰进行传递
public class Shoes implements IWearable { protected IWearable component; public void setComponent(IWearable component) {
this.component = component;
} @Override
public void operation() {
if (component != null) {
component.operation();
}
} }
package cn.no3.decorator.instance;
public class Weapons implements IWearable {
protected IWearable component;
public void setComponent(IWearable component) {
this.component = component;
}
@Override
public void operation() {
if (component != null) {
component.operation();
}
}
}
他们的子类都是重写父类operation()方法,最先调用(或者最后调用),super.operation();此处省略若干行
package cn.no3.decorator.instance;
public class WeaponA extends Weapons {
@Override
public void operation() {
// TODO Auto-generated method stub
super.operation();
System.out.println("装备了:霜之哀伤");
}
}
角色类
package cn.no3.decorator.instance;
public class Character implements IWearable{
@Override
public void operation() {
// TODO Auto-generated method stub
System.out.println("对一个人物进行装备:");
}
}
测试类:
package cn.no3.decorator.instance;
public class _Test {
public static void main(String[] args) {
//新建装备对象
Character concreteComponent = new Character();
ClotheA fantasyKiller = new ClotheA();
ClotheB bravingArmor = new ClotheB();
WeaponA frostmourne = new WeaponA();
WeaponB DoubleRoses = new WeaponB();
ShoesA shoes = new ShoesA();
//逐层包装
fantasyKiller.setComponent(concreteComponent);
bravingArmor.setComponent(fantasyKiller);
frostmourne.setComponent(bravingArmor);
DoubleRoses.setComponent(frostmourne);
shoes.setComponent(DoubleRoses);//shoes.setComponent(shoes)会陷入死循环
//输出最终结果
shoes.operation();
}
}
装饰模式是为已有功能动态地添加更多功能的一种方式
装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所需要装饰的对象。因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
装饰功能的核心是:把类中的装饰功能从类中搬出去。
Java学习笔记——设计模式之三.装饰模式的更多相关文章
- Java学习笔记——设计模式之五.工厂方法
水边一只青蛙在笑 --石头和水 工厂方法模式(Factory Method),定义了一个用于创建对象的接口,让实现类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 这里在简单和工厂的基础上 ...
- Java学习笔记——设计模式之二.策略模式
明确是王道 --Clean Code 先定义策略类 package cn.no2.strategy; public abstract class Strategy { //省略属性 //算法方法 pu ...
- Java学习笔记——设计模式之一.简单工厂
蜀道之难.难于上青天,侧身西望长咨嗟 --蜀道难 设计模式第一篇,简单工厂. 定义Operation类 package cn.no1.simplefactory; public abstract cl ...
- Java学习笔记——设计模式之十.观察者模式
观察者模式(Observer),定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. Subject类: ...
- Java学习笔记——设计模式之九.建造者模式
建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Product类: package cn.happy.design_pattern._09b ...
- Java学习笔记-设计模式
常见设计模式有23种,设计模式是解决某一类问题最行之有效的方法 单例设计模式 解决一个类在内存中只存在一个对象 思想 为了避免其他程序过多建立该类对象.先禁止其他程序建立该类对象 还为了让其他程序可以 ...
- Java学习笔记——设计模式之四.代理模式
To be, or not to be: that is the question. --<哈姆雷特> 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. 上代码: p ...
- Java学习笔记——设计模式之八.外观模式
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 子系统: package cn.happy.design_patter ...
- Java学习笔记——设计模式之七.模板方法模式
模板方法模式(TemplateMethod),定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 结构图: 代码: 算法骨架 ...
随机推荐
- iOS 文本转语音(TTS)详解:Swift
上一篇博客讲解了iOS的speech FrameWork语音识别的功能:http://www.cnblogs.com/qian-gu-ling/p/6599670.html,对应的这篇博客就写一下文本 ...
- datatables,表格
官方文档:https://datatables.net/ var dttblTaskOrderOptions={ order: [5, 'desc'], ajax:{ url:"order/ ...
- Kubernetes使用cephfs作为后端存储
这里使用了k8s自身的持久化卷存储机制:PV和PVC.各组件之间的关系参考下图: PV的Access Mode(访问模式) The access modes are: ReadWriteOnce – ...
- 从零开始学习springboot之springboot搭建
博主刚开始实习不久,还是小白一枚,被公司的各种新奇技术搞得眼花缭乱了好久,主要是用springboot和dubbo构建起来的项目.看完之后才知道springboot真的是java开发者的福音啊 话不多 ...
- [SinGuLaRiTy] 2017-03-27 综合性测试
[SinGuLaRiTy-1013] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 这是 三道 USACO 的题...... 第一题:奶牛飞 ...
- 老李分享:robotium常用API 2
断言: 具体请查看官网 断言方法assert(robotium特有的断言方式,实际项目中和Junit的assert方法配合使用) void assertCurrentActivity (String ...
- CSS3 转换、过渡和动画
一.转换 1.属性:transform 取值:none/transform-function(转换函数) 注意:如果要实现多个转换函数的话,可以用空格分开若干transform-function 2. ...
- Python学习_ConfigParse (转)
1.基本的读取配置文件 -read(filename) 直接读取ini文件内容 -sections() 得到所有的section,并以列表的形式返回 -options(section) 得到该se ...
- okHttp基础用法
获取okHttp..jar.包 1.联网获取jar包 2.本地添加 okHttp的使用 get请求 1.创建okHttpClient对象new OkHttpClient(); 2.创建一个请求对象Re ...
- JS中substring与substr的区别
Substring: 该方法可以有一个参数也可以有两个参数. (1) 一个参数: 示例: var str=“Olive”: str.substring(3); 结果:“ve” 说明:当substri ...