用23种设计模式打造一个cocos creator的游戏框架----(十六)亨元模式

1、模式标准

模式名称:亨元模式

模式分类:结构型

模式意图:运用共享技术有效地支持大量细粒度的对象

结构图:

适用于:

1、一个应用程序使用了大量的对象.

2、完全由于使用大量的对象,造成很大的存储开销。

3、对象的大多数状态都可变为外部状态。

4、如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。

5、应用程序不依赖于对象标识。由于 Flyweight 对象可以被共享,所以对于概念上明显有别的对象,标识测试将返回真值。

2、分析与设计

亨元模式和对象池模式有点像,但是有差别,对象池模式在我们前面提到的抽象工厂中,有提到部分代码,对象池模式一般有回收这个动作,回收对象一般会通过reset方法进行重置。而亨元模式不涉及reset回收,它是对大量颗粒度对象的共享技术。

前面在访问者模式中,我们简单设计了一个伤害系统,但是每次创建伤害访问者时都需要new一个,比如一次单体普通攻击:new MonomerAttackVisitor(100),但伤害事件在游戏中是大量存在,每次都new一个肯定是不友好的。这就需要将伤害值作为外部状态从对象中剥离出来,然后通过亨元模式将相同对象的共享起来。

结合前面的攻击访问者,重新描述一下意图:

意图:运用共享技术有效地支持大量细粒度的(攻击访问者)对象

3、开始打造

攻击访问者

TypeScript 复制代码
export interface IAttackVisitor {
    // 普通单位
    visitUnitItem(unitItem: IUnitItem, damage: number): void
    // 英雄单位
    visitHeroUnitItem(unitItem: IUnitItem, damage: number): void
}

// 单体攻击
export class MonomerAttackVisitor implements IAttackVisitor {

    // 普通单位
    visitUnitItem(unitItem: IUnitItem, damage: number): void {
        console.log('普通单位扣减 hp=' + damage)
        unitItem.subHp(damage)
    }
    // 英雄单位,受到伤害值为0.8
    visitHeroUnitItem(unitItem: IUnitItem, damage: number): void {
        console.log('英雄单位扣减 hp=' + damage)
        unitItem.subHp(damage * 0.8)
    }
}

// 群体攻击
export class GroupAttackVisitor implements IAttackVisitor {

    // 普通单位
    visitUnitItem(unitItem: IUnitItem, damage: number): void {
        unitItem.subHp(damage)
        // todo 周围单位也受到伤害
    }
    // 英雄单位,受到伤害值为0.8
    visitHeroUnitItem(unitItem: IUnitItem, damage: number): void {
        unitItem.subHp(damage * 0.8)
        // todo 周围单位也受到伤害
    }
}

亨元工厂

TypeScript 复制代码
// 亨元工厂
export class AttackVisitorFlyweightFactory {
    private flyweights: { [key: string]: IAttackVisitor } = {};

    public getFlyweight(key: string): IAttackVisitor {
        if (!this.flyweights[key]) {
            switch (key) {
                case 'monomer':
                    this.flyweights[key] = new MonomerAttackVisitor();
                    break;
                case 'group':
                    this.flyweights[key] = new GroupAttackVisitor();
                    break;
                // 添加其他 AttackVisitor 类型的处理逻辑
                default:
                    throw new Error('Invalid AttackVisitor type');
            }
        }
        return this.flyweights[key];
    }
}

4、开始使用

将攻击访问者工厂加入到全局单例里面

TypeScript 复制代码
export class SingletonInstance {
    // 设计模式5(单例模式)
    private static _instance: SingletonInstance = new this()
    static get instance(): SingletonInstance {
        return this._instance
    }
    static getInstance() {
        return this._instance
    }
    // game: TCSGame
    game: JCQGame
    // game: DemoGame
    // game: FeijianGame
    .....

    // 攻击访问者工厂
    attackVisitor: AttackVisitorFlyweightFactory = new AttackVisitorFlyweightFactory()
}

通过外观模式加入到xhgame中

TypeScript 复制代码
export class xhgame {
    // 设计模式10(外观模式)
    ....
    // 攻击访问者工厂
    static get attackVisitor() {
        return gameInstance.attackVisitor
    }
}

修改单位里面的attack方法

TypeScript 复制代码
export class UnitItem  extends Component implements IItem, IUnitItem {

    ad: number = 100;
    mp: number = 0;
    role: Fighter;
    private currentState: IUnitState = null;
    
    ......

    accept(visitor: IAttackVisitor, damage: number) {
        visitor.visitUnitItem(this, damage)
    }

    
    attack(unitItem: UnitItem<T>) {
        if (!this.canAttack()) {
            // 不能处理攻击的逻辑,可能是显示消息或者进入其他状态
            return;
        }
        // 尝试进入攻击状态
        this.getCurrentState().attack()
        let damage = this.ad
        let attackVisitor = xhgame.attackVisitor.getFlyweight('monomer')
        // let attackVisitor = new MonomerAttackVisitor(damage)
        unitItem.accept(attackVisitor, damage) // 伤害作为外部参数传入
    }
}
相关推荐
阿星AI工作室3 小时前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
xiezhr4 小时前
米哈游36岁程序员被曝复工当晚猝死出租屋内
游戏·程序员·游戏开发
_哆啦A梦1 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
爱搞虚幻的阿恺4 天前
Niagara粒子系统-超炫酷的闪电特效(加餐 纸牌螺旋上升效果)
游戏·游戏引擎
智算菩萨4 天前
儿童游乐空间的双维建构:室内淘气堡与室外亲子乐园的发展学理、功能分野与协同育人机制研究
游戏·游戏策划
marteker4 天前
房地产市场平台Zillow与《魔兽世界》合作展示游戏内房屋
游戏
阿闽ooo4 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4964 天前
js设计模式 --- 工厂模式
设计模式
wanhengidc4 天前
云手机 打造云端算力
运维·服务器·网络·游戏·智能手机
逆境不可逃4 天前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式