1、模式标准

模式名称:组合模式

模式分类:结构型

模式意图:将对象组合成树型结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性。

结构图:

适用于:

1、想表示对象的部分-整体层次结构。
2、希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

2、分析与设计

组合模式可以与命令模式结合使用,实现单命令,命令组,命令组内套命令组的功能。这样多一些常用的命令组,只需一个命令表达式就搞定了。

意图:将对象(命令)组合成树型结构以表示“部分-整体”的层次结构。

3、开始打造

命令类接口

// 命令类接口export interface ICommand {execute(): void;}

命令组

// 命令组export class GroupCommand implements ICommand {private name: string;private commands: ICommand[] = [];constructor(name: string) {this.name = name;}add(command: ICommand): void {this.commands.push(command);}remove(command: ICommand): void {const index = this.commands.indexOf(command);if (index !== -1) {this.commands.splice(index, 1);}}getChild(index: number): ICommand {return this.commands[index]}execute(): void {console.log(`Executing command group: ${this.name}`);// 执行所有子命令for (const command of this.commands) {command.execute();}}}

单命令

// 具体技能命令类 - 小技能export class SmallSkillCommand implements ICommand {execute(): void {console.log("释放小技能");}}// 具体技能命令类 - 中技能export class MediumSkillCommand implements ICommand {execute(): void {console.log("释放中技能");}}// 具体技能命令类 - 大技能export class LargeSkillCommand implements ICommand {execute(): void {console.log("释放大技能");}}

4、开始使用

修改上次用过的解析器模式的上下文,新增commandId == ‘attackgroup’

// 单位 操作命令 另一个单位export class UnitCommandUnitContext {command: ICommand = nullfromUnitItem: UnitItem = nulltoUnitItem: UnitItem = nullgetUnitItem(unitItemId: string) {return xhgame.game.battleEntity.model.unitItemMap.get(unitItemId)}getCommand(commandId: string) {if (commandId == 'attackgroup') {const command1 = new SmallSkillCommand();const command2 = new MediumSkillCommand();const command3 = new LargeSkillCommand();// 先生成一个子命令组const commandGroup1 = new GroupCommand("commandGroup1");commandGroup1.add(command1);commandGroup1.add(command2);// 再生成一个含子命令组及多个单命令的命令组const commandGroup2 = new GroupCommand("commandGroup2");commandGroup2.add(commandGroup1);commandGroup2.add(command1);commandGroup2.add(command2);commandGroup2.add(command3);return commandGroup2}return new AttackCommand(null, null)}setCommand(command: ICommand) {this.command = command}setUnitItem(unitItem: UnitItem) {if (this.fromUnitItem == null) {this.fromUnitItem = unitItem}if (this.toUnitItem == null) {this.toUnitItem = unitItem}}executeCommand() {if (this.command instanceof AttackCommand) {this.command.setUnitItem(this.fromUnitItem)this.command.setTargetUnitItem(this.toUnitItem)this.command.execute()} else {this.command.execute()}}}

修改表达式

......// 修改表达式,现在一个表达式,实际干了n多个命令const commandText = "[[UnitItem.20]]{{attackgroup}}[[UnitItem.21]]";......

效果