模式名称:组合模式
模式分类:结构型
模式意图:将对象组合成树型结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性。
结构图:
适用于:
1、想表示对象的部分-整体层次结构。
2、希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
组合模式可以与命令模式结合使用,实现单命令,命令组,命令组内套命令组的功能。这样多一些常用的命令组,只需一个命令表达式就搞定了。
意图:将对象(命令)组合成树型结构以表示“部分-整体”的层次结构。
命令类接口
// 命令类接口
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("释放大技能");
}
}
修改上次用过的解析器模式的上下文,新增commandId == 'attackgroup'
// 单位 操作命令 另一个单位
export class UnitCommandUnitContext {
command: ICommand = null
fromUnitItem: UnitItem<any> = null
toUnitItem: UnitItem<any> = null
getUnitItem(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<any>) {
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]]";
......
效果