博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GoF之装饰模式遇见王者荣耀、刺激战场
阅读量:4103 次
发布时间:2019-05-25

本文共 5152 字,大约阅读时间需要 17 分钟。

装饰(Decorator Pattern)模式

在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。就增加功能来说,装饰模式比生成子类更为灵活。

使用场景:

  1. 需要扩展一个类的功能,或给一个类添加附加职责。

  2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。

  3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

4.当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

优点:

1.Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。

  1. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

  1. 这种比继承更加灵活机动的特性,同时也更加复杂。

  2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

3.装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

具体实现:

王者荣耀英雄角色安琪拉,学三个技能,1(Q)、2(W)、3(E)的动态实现。

//Component 英雄接口 publicinterface Hero { //学习技能 void learnSkills();}//ConcreteComponent具体英雄安琪拉,这里可以用新的英雄实现类来增加新英雄角色public class Angela implements Hero { private String name; public Angela(Stringname) { this.name = name; } @Override public void learnSkills() { System.out.println(name + "学习了以上技能!"); }} //Decorator 技能池 通过增加英雄实现类,可以增加英雄技能池、皮肤池、武器池等待 public abstractSkills implements Hero{ //持有一个英雄对象接口 private Hero hero; public Skills(Herohero) { this.hero = hero; } @Override public void learnSkills() { if(hero != null) hero.learnSkills(); } }//ConreteDecorator技能:Q 通过增加技能实现类即可增加技能种类public class Skill_Q extends Skills{ private String skillName; public Skill_Q(Hero hero,String skillName) { super(hero); this.skillName = skillName; } @Override public voidlearnSkills() { System.out.println("学习技能Q:"+skillName); super.learnSkills(); }} //ConreteDecorator 技能:W public class Skill_W extends Skills{ private String skillName; public Skill_W(Hero hero,String skillName) { super(hero); this.skillName = skillName; } @Override public voidlearnSkills() { System.out.println("学习技能W:"+ skillName); super.learnSkills(); } } //ConreteDecorator 技能:E public class Skill_E extends Skills{ private String skillName; public Skill_E(Hero hero,StringskillName) { super(hero); this.skillName =skillName; } @Override public voidlearnSkills() { System.out.println("学习技能E:"+skillName); super.learnSkills(); } } //客户端:召唤师  public class Player { public static void main(String[]args) { //选择英雄 有多少英雄接口实现类 就有多少种选择 Hero hero = newAngela("安琪拉"); Skills skills = new Skills(hero); //装扮的顺序不限 此为单独学习技能 Skills q = new Skill_Q(skills,"火球术"); Skillsw = new Skill_W(skills,"混沌火种"); Skillse = new Skill_E(skills,"制热光辉"); //学习技能 q.learnSkills(); w.learnSkills(); e.learnSkills(); //一整套技能学习 Skills q = newSkill_Q(skills,"火球术"); Skills w = newSkill_W(q,"混沌火种"); Skills e = newSkill_E(w,"制热光辉"); e.learnSkills(); }}

《刺激战场》游戏里面装备98K枪械,更换弹夹、倍镜。

Kar 98K有5发子弹;

装上弹匣后有10发子弹;

装上4倍镜后可以进行4倍瞄准;

装上8倍镜后可以进行4倍瞄准、8倍瞄准。

//定义具备射击功能的枪械接口public interface Gun { //射击 publicvoid fire();}//创建具体的枪械实现类Kar98K,默认5发子弹public class Kar98K implements Gun { @Override publicvoid fire() { System.out.println("射击5次"); }}//对枪械的弹夹进行装饰,抽象实现枪械接口public abstract class AbstractMagazine implements Gun{//持有枪械对象 private Gun gun; public AbstractMagazine(Gun gun) { this.gun = gun; } @Override public void fire() { gun.fire(); }}//枪械弹夹装饰的具体实现类,子弹增加至10发public class Magazine extends AbstractMagazine { public Magazine(Gun gun) { super(gun); } @Override public void fire() { System.out.println("射击10次"); }}//客户端public class Player { public static void main(String[] args) { //捡起一把98K Gun gun = newKar98K(); //射击5次 gun.fire(); //装饰上弹匣 gun = new Magazine(gun); //射击10次 gun.fire(); } }

现在我要装上4倍镜,使它具有4倍瞄准功能,这是枪支原本没有的功能。

扩展枪支接口功能:

//对枪械接口的继承,再增加倍镜装饰public interface Aim4X extends Gun { public void aim4X();}public abstract class AbstractTelescope4X implements Aim4X { private Gun gun; public AbstractTelescope4X(Gun gun) { this.gun = gun; } @Override public void fire() { gun.fire(); }}public class Telescope4X extends AbstractTelescope4X { public Telescope4X(Gun gun) { super(gun); } @Override publicvoid aim4X() { System.out.println("已进入4倍瞄准模式"); }}//55式4倍镜public class Telescope4X55 extends AbstractTelescope4X { public Telescope4X55(Gun gun) { super(gun); } @Override publicvoid aim4X() { System.out.println("4倍超级瞄准已部署"); } } public class Player { public static void main(String[] args) { //捡起一把98K Gun gun = newKar98K(); //装饰上4倍镜 Aim4X aim4X = new Telescope4X(gun); //4倍瞄准] aim4X.aim4X(); //射击 aim4X.fire(); //先装饰上弹匣 gun = new Magazine(gun); //再装饰上4倍镜 aim4X = new Telescope4X(gun); //4倍瞄准 aim4X.aim4X(); //换上55式4倍镜 aim4X = new Telescope4X55(gun); //射击! aim4X.fire(); } }

现在我要装上8倍镜,它具有4倍瞄准功能,也具有8倍瞄准功能。

扩展接口:

public interface Aim8X extends Aim4X { public void aim8X(); }public abstract class AbstractTelescope8X implements Aim8X { private Gun gun; public AbstractTelescope8X(Gun gun) { this.gun = gun; } @Override public void fire() { gun.fire(); } }public class Telescope8X extends AbstractTelescope8X { public Telescope8X(Gun gun) { super(gun); } @Override publicvoid aim8X() { System.out.println("进入8倍瞄准模式"); } @Override publicvoid aim4X() { System.out.println("进入4倍瞄准模式"); }} public class Player { public static void main(String[] args) { //先装饰上弹匣 gun = new Magazine(gun); //再装饰上8倍镜 aim8X = new Telescope8X(gun); //8倍瞄准 aim8X.aim8X(); //敌人很近,换4倍 aim8X.aim4X(); //射击! aim8X.fire(); } }

原文:https://mp.weixin.qq.com/s/hxxNd2QJwKdOecLiDmJCcA

作者:专注一行代码

来源:微信公众号

免费分享java技术资料,需要的朋友可以在关注后私信我

在这里插入图片描述

在这里插入图片描述

转载地址:http://wfusi.baihongyu.com/

你可能感兴趣的文章
android怎么修改状态栏集锦
查看>>
Android基础教程之---Android状态栏提醒(Notification,NotificationManager)的使用! .
查看>>
【Android】状态栏通知Notification、NotificationManager详解
查看>>
如何在Android 4.0 ICS中禁用StatusBar | SystemBar | 状态栏
查看>>
android ics SystemUI详解
查看>>
android systemUI--Notification 整理
查看>>
状态栏SystemUI的启动过程
查看>>
Android状态栏功能介绍
查看>>
Notification的显示过程
查看>>
Android init 启动过程分析1
查看>>
Android init 启动过程分析2
查看>>
关于android 系统开发文章整理
查看>>
状态栏的定制
查看>>
Android的联通性---Bluetooth(一)
查看>>
Android的联通性---Bluetooth(二)
查看>>
android启动过程配置文件的解析与语法
查看>>
android系统开发(一)-HAL层开发基础
查看>>
android系统开发(二)-背光模块
查看>>
android系统开发(三)-SDCARD
查看>>
50个Android开发人员必备UI效果源码[转载]
查看>>