定义:
装饰器模式就是一个可以非常灵活的动态扩展类功能的设计模式,它采用组合的方式取代继承,使得各个功能的扩展更加独立和灵活
特点:
(1) 装饰对象和真实对象有相同的接口。这样客户端对象就可以以和真实对象相同的方式和装饰对象交互。
(2) 装饰对象包含一个真实对象的索引(reference)
(3) 装饰对象接受所有的来自客户端的请求。它把这些请求转发给真实的对象。
(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。
结构图:
角色:
- 抽象构件(component)角色 :这个角色用来规范被装饰的对象,一般用接口方式给出。
- 具体构件(concrete component )角色 :被装饰的类。
- 装饰(decorator)角色 :实现了抽象构件,持有一个构件对象的实例,通常是一个抽象类。
- 具体 (concrete decorator ) 装饰角色 :负责给具体构件添加附加职责的类。在实际使用中多数情况下装饰角色和具体装饰角色可能由一个类来承担
这个结构中最关键的是,装饰角色持有一个构件对象的实例。这样,需要装饰的实例,才能够传入到装饰器中,让装饰器对其进行装饰。同时,在多个装饰器共同装饰的情况下,还可以把前面的装饰器传入到后面的装饰器中,由最后的装饰器调用动作。因为它们实现了同样的接口,这样做是允许的。
demo:
英雄联盟相信大家都玩过,团战可以输,提莫必须死 想必大家都知道。没错就是这只提莫,我们今天就是通过一只从最开始只会普攻的提莫开始,直到学会所有技能的例子,来为大家演示一下装饰器模式的使用。
(抽象构件角色:也可以是接口,这里我定义成了抽象类) HeroComponent.java
package com.tianlh.service.design_pattern.Decorator;
/**
* Created by wb-tianlihui on 2017/11/21.
*/
public abstract class HeroComponent {
/**
* 定义每个英雄可以普通攻击
*/
public abstract void Pugong();
}
具体构件角色: TimorComponent.java
package com.tianlh.service.design_pattern.Decorator;
/**
* Created by wb-tianlihui on 2017/11/21.
*/
public class TimorComponent extends HeroComponent {
private final String HERO_NAME = "提莫";
@Override
public void Pugong() {
System.out.println("我是" + HERO_NAME + "我可以普通攻击!");
}
}
装饰(decorator)角色 : Decorator.java
package com.tianlh.service.design_pattern.Decorator;
/**
* Created by wb-tianlihui on 2017/11/21.
*/
public abstract class Decorator extends HeroComponent {
protected HeroComponent component;
/**
* 构造方法,传入组件对象
* @param component 组件对象
*/
public Decorator(HeroComponent component) {
this.component = component;
}
@Override
public void Pugong(){
component.Pugong();
}
}
具体装饰角色 : QDecorator.java WDecorator.java EDecorator.java RDecorator.java
package com.tianlh.service.design_pattern.Decorator;
/**
* Created by wb-tianlihui on 2017/11/21.
*/
public class QDecorator extends Decorator {
private final String SKILL_NAME = "致盲吹箭";
/**
* 构造方法,传入组件对象
* @param component 组件对象
*/
public QDecorator(HeroComponent component) {
super(component);
}
public void customFunction(){
System.out.println("我拥有了Q技能:" + SKILL_NAME);
}
@Override
public void Pugong() {
super.Pugong();
customFunction();
}
}
package com.tianlh.service.design_pattern.Decorator;
/**
* Created by wb-tianlihui on 2017/11/21.
*/
public class WDecorator extends Decorator {
private final String SKILL_NAME = "小莫快跑";
/**
* 构造方法,传入组件对象
* @param component 组件对象
*/
public WDecorator(HeroComponent component) {
super(component);
}
public void customFunction(){
System.out.println("我拥有了W技能:" + SKILL_NAME);
}
@Override
public void Pugong() {
super.Pugong();
customFunction();
}
}
package com.tianlh.service.design_pattern.Decorator;
/**
* Created by wb-tianlihui on 2017/11/23.
*/
public class EDecorator extends Decorator {
private final String SKILL_NAME = "毒性射击";
/**
* 构造方法,传入组件对象
* @param component 组件对象
*/
public EDecorator(HeroComponent component) {
super(component);
}
public void customFunction(){
System.out.println("我拥有了E技能:" + SKILL_NAME);
}
@Override
public void Pugong() {
super.Pugong();
customFunction();
}
}
package com.tianlh.service.design_pattern.Decorator;
/**
* Created by wb-tianlihui on 2017/11/23.
*/
public class RDecorator extends Decorator {
private final String SKILL_NAME = "种蘑菇";
/**
* 构造方法,传入组件对象
* @param component 组件对象
*/
public RDecorator(HeroComponent component) {
super(component);
}
public void customFunction(){
System.out.println("我拥有了R技能:" + SKILL_NAME);
}
@Override
public void Pugong() {
super.Pugong();
customFunction();
}
}
具体调用逻辑 : Main.java
package com.tianlh.service.design_pattern.Decorator;
/**
* Created by wb-tianlihui on 2017/11/21.
*/
public class Main {
public static void main(String[] args) {
//首先创建需要被装饰的原始对象(即要被装饰的对象)
HeroComponent c1 = new TimorComponent();
//给对象增加Q技能
Decorator decoratorQ = new QDecorator(c1);
//Q技能的基础上,增加W技能
Decorator decoratorW = new WDecorator(decoratorQ);
//W技能的基础上,增加E技能
Decorator decoratorE = new EDecorator(decoratorW);
//E技能的基础上,增加R技能
Decorator decoratorR = new RDecorator(decoratorE);
decoratorR.Pugong();
}
}
输出结果:
我是提莫我可以普通攻击!
我拥有了Q技能:致盲吹箭
我拥有了W技能:小莫快跑
我拥有了E技能:毒性射击
我拥有了R技能:种蘑菇