装饰者模式定义:装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方法。
装饰者模式是对原有功能增加新的功能(行为),当然,给一个类增加新功能(行为)我们可以使用继承或组合。但是单独的使用继承或组合实现将会产生大量的类,而使用装饰者模式可以在保持良好的扩展性同时避免产生大量的类。
优点:
- 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
- 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
- 装饰器模式完全遵守开闭原则
缺点:过度使用会产生很多子类
装饰者模式结构:
- 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
- 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
- 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
- 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
装饰者模式实现:
场景说明:构件为:LOL里面的英雄。装饰为LOL里面的装备。使用云顶之弈模式为为背景。
package com.wly.DesignPatterns;
/**
* @program: StudyDome
* @author: yuanzhang
* @create: 2020-12-02 15:29
**/
public class Decorator {
public static void main(String[] args) {
System.out.println("获得一个英雄---泰隆");
BaseRole shadowTalon = new ShadowTalon();
System.out.println("-----------:"+shadowTalon.getEquipment());
System.out.println("给他装个电刀");
shadowTalon = new Electrotome(shadowTalon);
System.out.println("-----------:"+shadowTalon.getEquipment());
System.out.println("给它装个轻语");
shadowTalon = new Whisper(shadowTalon);
System.out.println("-----------:"+shadowTalon.getEquipment());
}
}
/**
* @Annotation:抽象构件 -----角色
* @Author: yuanzhang
* @Date: 15:35
*/
abstract class BaseRole{
/** 获取装备*/
protected abstract String getEquipment();
}
/**
* @Annotation:具体构件----英雄泰隆
* @Author: yuanzhang
* @Date: 15:35
*/
class ShadowTalon extends BaseRole{
@Override
protected String getEquipment() {
return "ShadowTalon";
}
}
/**
* @Annotation:抽象装饰----装备库
* @Author: yuanzhang
* @Date: 15:40
*/
class EquipmentLibrary extends BaseRole{
protected BaseRole role;
EquipmentLibrary(BaseRole role){
this.role = role;
}
@Override
protected String getEquipment() {
return role.getEquipment()+"没装备";
}
}
/**
* @Annotation:具体装饰----电刀
* @Author: yuanzhang
* @Date: 15:47
*/
class Electrotome extends EquipmentLibrary{
Electrotome(BaseRole role) {
super(role);
}
@Override
protected String getEquipment(){
return role.getEquipment()+"|电刀";
}
}
/**
* @Annotation:具体装饰----最后的轻语
* @Author: yuanzhang
* @Date: 15:57
*/
class Whisper extends EquipmentLibrary{
Whisper(BaseRole role){
super(role);
}
@Override
protected String getEquipment() {
return role.getEquipment()+"|轻语";
}
}
输出:
获得一个英雄---泰隆 -----------:ShadowTalon 给他装个电刀 -----------:ShadowTalon|电刀 给它装个轻语 -----------:ShadowTalon|电刀|轻语