当前位置:   article > 正文

用23种设计模式打造一个cocos creator的游戏框架----(十一)桥接模式_cocoscreatorigembridge

cocoscreatorigembridge

1、模式标准

模式名称:桥接模式

模式分类:结构型

模式意图:将抽象部分与其实现部分分离,使它们都可以独立地变化。

结构图:

适用于:

1、不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如,这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。

2、类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这是 Bridge 模式使得开发者可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。

3、对一个抽象的实现部分的修改应对客户不产生影响,即客户代码不必重新编译

4、想在多个对象间共享实现 (可能使用引用计数),但同时要求客户并不知道这一点 

主要成员:

  • 抽象类(Abstraction):定义和保存客户端的引用,维护与实现对象之间的关联关系。
  • 扩展抽象类(Refined Abstraction):扩展和精化抽象类中的接口定义。
  • 实现类接口(Implementor):定义实现类的接口,可以与抽象类的接口相互独立。
  • 具体实现类(Concrete Implementor):具体实现接口,在不同的实现类中提供基本操作的不同实现。

2、分析与设计  

桥接模式,通俗点讲就如同嫁接,比如有一个树,会开花结果,我给它嫁接苹果枝,在开花结果后,长的是苹果。如果嫁接橘子枝,在开花结果后,长的是橘子。

当前的例子用在攻击者使用武器中的攻击功能。攻击者使用武器中的攻击方法作为抽象方法,具体如何攻击需要武器来实现,武器作为一个独立的存在,具有攻击功能外还具有售卖功能。我们直接桥接了其中的攻击方法。桥接和策略在某些方法上有些像,但是桥接模式与策略模式的差异之处在于,桥接只是桥接了其中的一个或几个方法,而策略模式是替换了整个策略算法。

意图:将抽象部分(攻击)与其实现部分(剑攻击和弓攻击)分离,使它们都可以独立地变化(剑除了攻击方法之外还有售卖等其他功能,当前只是桥接了攻击功能)。

3、开始打造

  1. // 战斗方式
  2. export abstract class Fighter {
  3. // protected attackStrategy: IAttackStrategy;
  4. protected weapon: IWeapon;
  5. constructor(weapon: IWeapon) {
  6. this.weapon = weapon;
  7. }
  8. // 设计模式,桥接模式
  9. // 使用了武器里面的攻击方法(武器可能还有售卖的方法,且是独立)
  10. attack(fromUnitItem: UnitItem<any>, toUnitItem: UnitItem<any>): void {
  11. this.weapon.attack(fromUnitItem, toUnitItem);
  12. }
  13. // 更换武器
  14. setWeapon(weapon: IWeapon): void {
  15. this.weapon = weapon;
  16. }
  17. abstract getType(): string
  18. }
  19. // 普通攻击者
  20. export class NormalFighter extends Fighter {
  21. constructor(weapon: IWeapon) {
  22. super(weapon);
  23. }
  24. getType(): string {
  25. return 'NormalFighter' + '' // todo weapon
  26. }
  27. }
  1. // 武器(单位攻击属性)接口
  2. export interface IWeapon {
  3. attackStrategy: IAttackStrategy
  4. price: number
  5. sell(): number
  6. getEffect(): string;
  7. attack(fromUnitItem: UnitItem<any>, toUnitItem: UnitItem<any>): void
  8. setAttackStrategy(attackStrategy: IAttackStrategy): void
  9. }
  10. export abstract class Weapon implements IWeapon {
  11. attackStrategy: IAttackStrategy
  12. price: number
  13. itemNo: string
  14. constructor(attackStrategy: IAttackStrategy, price: number, itemNo: string) {
  15. this.attackStrategy = attackStrategy
  16. this.price = price
  17. this.itemNo = itemNo
  18. }
  19. sell(): number {
  20. return this.price
  21. }
  22. getEffect(): string {
  23. return this.itemNo
  24. }
  25. // 攻击者的抽象attack方法桥接到了此处武器的attack方法
  26. attack(fromUnitItem: UnitItem<any>, toUnitItem: UnitItem<any>): void {
  27. // 武器的attack实现,用具体攻击策略实现
  28. this.attackStrategy.doAction(fromUnitItem, toUnitItem, this.getEffect())
  29. }
  30. setAttackStrategy(attackStrategy: IAttackStrategy) {
  31. this.attackStrategy = attackStrategy
  32. }
  33. }
  34. // 剑
  35. export class Sword extends Weapon {
  36. constructor(ItemNo: string) {
  37. super(new MeleeAttack(), 100, ItemNo)
  38. }
  39. }
  40. // 斧头
  41. export class Axe extends Weapon {
  42. constructor(ItemNo: string) {
  43. super(new MeleeAttack(), 100, ItemNo)
  44. }
  45. }
  46. // 弓
  47. export class Bow extends Weapon {
  48. constructor(ItemNo: string) {
  49. super(new RangedAttack(), 100, ItemNo)
  50. }
  51. }

4、开始使用

单位

  1. export class UnitItem extends Component implements IItem, IUnitItem {
  2. ad: number = 100;
  3. mp: number = 0;
  4. // 攻击方法
  5. fighter: Fighter;
  6. private currentState: IUnitState = null;
  7. .....
  8. setFighter(fighter: Fighter): void {
  9. this.fighter = fighter;
  10. }
  11. }

  1. // 设计模式:享元模式
  2. // 运用共享技术有效地支持大量细粒度的对象
  3. export class FlyweightFactory {
  4. // 攻击访问者s(伤害计算系统)
  5. private attackVisitors: { [key: string]: IAttackVisitor } = {};
  6. // 单位攻击方式方法
  7. private fighters: { [key: string]: Fighter } = {};
  8. 。。。。。
  9. public getFighter(key: string): Fighter {
  10. if (!this.fighters[key]) {
  11. switch (key) {
  12. case FighterType.Jianbing:
  13. this.fighters[key] = new NormalFighter(new Sword('bbc'));
  14. break;
  15. case FighterType.Gongbing:
  16. this.fighters[key] = new NormalFighter(new Bow('bbc'));
  17. break;
  18. default:
  19. throw new Error('无效的FighterType');
  20. }
  21. }
  22. return this.fighters[key];
  23. }
  24. }

简单示例

  1. let unitItem001 = xhgame.itemFactory.createUnitItem('shibing_001')
  2. let unitItem002 = xhgame.itemFactory.createUnitItem('shibing_002')
  3. unitItem001.setFighter(xhgame.flyweightFactory.getFighter(FighterType.Jianbing));
  4. unitItem002.setFighter(xhgame.flyweightFactory.getFighter(FighterType.Jianbing));
  5. console.log('unitItem001对unitItem002发起了攻击')
  6. unitItem001.attack(unitItem002)
  7. console.log('unitItem002对unitItem001发起了攻击')
  8. unitItem002.attack(unitItem001)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/152455
推荐阅读
相关标签
  

闽ICP备14008679号