Composite设计模式困境与Command设计模式PacMan扩展需求问询
Hey there! Sounds like you're trying to bolt the Composite pattern onto your existing Command-based Pac-Man setup—probably to let users chain together multiple commands (like "move up, then right, then attack") into a single executable sequence, right? Let's walk through how to make this work seamlessly without breaking your current code:
First, make sure every single command (movement, attack, and your upcoming composite commands) implements the same core Command interface. This is the backbone of making Composite work—callers won't need to distinguish between a single command and a whole sequence.
// Base Command interface (you probably already have this!) public interface Command { void execute(); } // Example single commands you already have public class MoveRightCommand implements Command { private PacMan pacMan; public MoveRightCommand(PacMan pacMan) { this.pacMan = pacMan; } @Override public void execute() { pacMan.moveRight(); } } public class AttackCommand implements Command { private PacMan pacMan; public AttackCommand(PacMan pacMan) { this.pacMan = pacMan; } @Override public void execute() { pacMan.attackNearbyGhosts(); } }
This class will act as a "container" for multiple commands. It implements the same Command interface, so it can be treated exactly like any single command in your system.
import java.util.ArrayList; import java.util.List; public class CompositeCommand implements Command { private final List<Command> subCommands = new ArrayList<>(); // Add a command to the sequence public void addCommand(Command command) { subCommands.add(command); } // Remove a command if you need to edit the sequence public void removeCommand(Command command) { subCommands.remove(command); } @Override public void execute() { // Run every command in the sequence in order for (Command cmd : subCommands) { cmd.execute(); } } }
Now you can build complex command sequences and execute them just like any single command. For example, if a user wants a "dash-and-attack" sequence:
// Initialize your PacMan instance PacMan playerPacMan = new PacMan(); // Create individual commands Command moveRight = new MoveRightCommand(playerPacMan); Command moveRightAgain = new MoveRightCommand(playerPacMan); Command attack = new AttackCommand(playerPacMan); // Build the composite sequence CompositeCommand dashAndAttack = new CompositeCommand(); dashAndAttack.addCommand(moveRight); dashAndAttack.addCommand(moveRightAgain); dashAndAttack.addCommand(attack); // Execute the whole sequence with one call! dashAndAttack.execute();
If your game supports undoing commands, extend the Command interface and update the Composite class to handle undo in reverse order (since you want to undo the last command first):
// Updated Command interface public interface Command { void execute(); void undo(); } // Update single commands to implement undo public class MoveRightCommand implements Command { // ... existing code ... @Override public void undo() { pacMan.moveLeft(); // Undo right move with left move } } // Update CompositeCommand for undo @Override public void undo() { // Reverse the list to undo commands in reverse execution order List<Command> reversedCommands = new ArrayList<>(subCommands); Collections.reverse(reversedCommands); for (Command cmd : reversedCommands) { cmd.undo(); } }
Quick Tips to Avoid Headaches
- Keep the
Commandinterface minimal—only include methods every command (single and composite) needs to implement. - You can nest Composite commands inside other Composite commands if you want even more complex sequences (like a "pre-game routine" that combines multiple smaller sequences).
- If you need to save/load command sequences, make sure your
Commandimplementations are serializable.
内容的提问来源于stack exchange,提问作者Noor Ahmed

