装饰器模式允许向一个现有的对象添加新功能,同时又不改变其结构。装饰器模式用于对现有类的包装,它属于结构型模式。
一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
如要动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
场景模拟
装饰器模式在游戏中应用非常广泛,比如LOL英雄升级,每次英雄升级都会附加一个额外技能学习的场景。英雄升级是原有结构,所学习技能便是一个附加描述。
interface Hero {
learnSkills(): void;
}
class BlindMonk implements Hero {
private name: String;
level: number = 0;
constructor(name: String) {
this.name = name;
}
learnSkills(): void {
console.log(this.name + "学习了以下技能!")
}
}
class Skills implements Hero {
private hero: Hero;
constructor(hero: Hero) {
this.hero = hero;
}
learnSkills(): void {
if (this.hero != null) {
this.hero.learnSkills();
}
}
}
class Skill_Q extends Skills {
private skillName: String;
private level: number;
constructor(hero: Hero, skillName: String, level: number) {
super(hero);
this.skillName = skillName;
this.level = level;
}
learnSkills(): void {
super.learnSkills();
console.log(this.level + "级学习了Q技能:" + this.skillName)
}
}
class Skill_W extends Skills {
private skillName: String;
private level: number;
constructor(hero: Hero, skillName: String, level: number) {
super(hero);
this.skillName = skillName;
this.level = level;
}
learnSkills(): void {
super.learnSkills();
console.log(this.level + "级学习了W技能:" + this.skillName)
}
}
class Skill_E extends Skills {
private skillName: String;
private level: number;
constructor(hero: Hero, skillName: String, level: number) {
super(hero);
this.skillName = skillName;
this.level = level;
}
learnSkills(): void {
super.learnSkills();
console.log(this.level + "级学习了E技能:" + this.skillName);
}
}
class Skill_R extends Skills {
private skillName: String;
private level: number;
constructor(hero: Hero, skillName: String, level: number) {
super(hero);
this.skillName = skillName;
this.level = level;
}
learnSkills(): void {
super.learnSkills();
console.log(this.level + "级学习了R技能:" + this.skillName);
}
}
//选择英雄
let hero:Hero = new BlindMonk("李青");
let skills:Skills = new Skills(hero);
// 1级学q
let lev1:Skills = new Skill_Q(skills,"天音波/回音击",1);
// 2级学w
let lev2:Skills = new Skill_W(lev1,"金钟罩/铁布衫",2);
// 3级学e
let lev3:Skills = new Skill_E(lev2,"天雷破/摧筋断骨",3);
// 4级学q
let lev4:Skills = new Skill_Q(lev3,"天音波/回音击",4);
// 5级学w
let lev5:Skills = new Skill_W(lev4,"金钟罩/铁布衫",5);
// 6级学r
let lev6:Skills = new Skill_R(lev5,"猛龙摆尾",6);
//学习技能
lev6.learnSkills();