1、模式标准
模式名称:模板方法模式
模式分类:行为型
模式意图:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
结构图:
适用于:
1、一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2、各子类中公共的行为应被提取出来并集中到一个公共父类中,以避免代码重复。
3、控制子类扩展。模板方法旨在特定点调用“hook”操作(默认的行为,子类可以在必要时进行重定义扩展),这就只允许在这些点进行扩展。
2、分析与设计
模板方法模式还是比较简单的,在这里我们以前面第一个的构建好的游戏为例。每个游戏在游戏开始的时候,都有初始化玩家,加载资源,进入游戏大概这三个过程的小骨架。修改一下我们的意图
意图:定义一个操作中(游戏开始)的算法骨架(加载过程),而将一些步骤延迟到子类(每个游戏)中。
3、开始打造
抽象游戏基类
export abstract class AbstractGame implements IGame {......abstract initPlayer(): anyabstract loadingAndInit(): Promise<void>abstract enterGame(): voidasync start() {this.initPlayer()await this.loadingAndInit();this.enterGame()}}
4、开始使用
main.ts
onLoad() {window['xhgame'] = xhgame // 方便console中查看全局const gameDesign = new GameDesign();switch (this.gameCode) {case 'demo': // demogameDesign.setGameBuilder(new DemoGameBuilder(this));gameInstance.game = gameDesign.buildGame<DemoGame>()// 添加有update的系统xhgame.game.updateSystems.push(GameMoveSystem)xhgame.game.updateSystems.push(GameLoadingSystem)break;case 'feijian': // 飞剑gameDesign.setGameBuilder(new FeijianGameBuilder(this));gameInstance.game = gameDesign.buildGame<FeijianGame>()// 添加有update的系统xhgame.game.updateSystems.push(GameMoveSystem)xhgame.game.updateSystems.push(GameLoadingSystem)break;}gameInstance.game.start()}
export class DemoGame extends AbstractGame{/** 游戏实体 */gameEntity: DemoGameEntity/** 玩家实体 */playerEntity: DemoPlayerEntity/** 战役实体 */battleEntity: DemoBattleEntity// 登录并初始化玩家initPlayer() {const player_entity = xhgame.game.playerEntityplayer_entity.attachComponent(PlayerLoginComp).callback = () => {player_entity.attachComponent(PlayerResourceComp) // 玩家资源组件}}// 加载资源loadingAndInit() {return new Promise<void>((resolve, reject) => {GameLoadingSystem.startLoading(async (resolveCallback: Function) => {xhgame.camera.normal()await this.loadMap()await this.initBattle()resolveCallback && resolveCallback()},() => {resolve()})})}// 进入游戏enterGame() {let unitItem001 = xhgame.itemFactory.createUnitItem('kuloubing', UnitType.UnitSpine)let unitItem002 = xhgame.itemFactory.createUnitItem('kuloubing', UnitType.UnitSpine)unitItem001.idle()unitItem002.idle()}}