策略模式适配不同参数数量命令执行的设计问题咨询
用策略模式处理多参数/无参数命令的实现思路
这个场景太常见了!我之前做命令行交互工具的时候也踩过类似的坑,用策略模式来处理确实是个优雅的方案,咱们一步步来实现:
1. 定义统一的命令接口
首先要给所有命令制定一个统一的契约,不管有没有参数,都接收一个参数列表(无参数时就是空列表),这样接口的一致性能让后续扩展更顺畅。另外加一个获取命令名称的方法,方便后续匹配执行:
public interface ICommandExecutor { // 统一接收参数列表,空列表代表无参数 String execute(List<String> args); // 返回命令的标识名称(比如"create_room"、"exit") String getCommandName(); }
2. 实现具体的命令执行者
针对不同类型的命令分别实现接口,各自处理参数校验和业务逻辑:
无参数命令示例(ExitCommand)
public class ExitCommand implements ICommandExecutor { @Override public String execute(List<String> args) { // 无参数命令直接执行逻辑,不需要处理args return "程序已退出"; } @Override public String getCommandName() { return "exit"; } }
带参数命令示例(CreateRoomCommand)
public class CreateRoomCommand implements ICommandExecutor { @Override public String execute(List<String> args) { // 先校验参数数量是否符合要求 if (args.size() != 1) { return "错误:create_room命令需要1个参数(房间号)"; } try { int roomId = Integer.parseInt(args.get(0)); // 这里写创建房间的具体业务逻辑,比如存储到数据库 return "成功创建房间:" + roomId; } catch (NumberFormatException e) { return "错误:房间号必须是整数"; } } @Override public String getCommandName() { return "create_room"; } }
3. 搭建命令管理上下文(策略容器)
这个类负责注册所有命令、解析用户输入、匹配并执行对应的命令,相当于策略模式里的上下文角色:
import java.util.HashMap; import java.util.List; import java.util.Map; public class CommandManager { private final Map<String, ICommandExecutor> commandMap = new HashMap<>(); // 注册命令到容器 public void registerCommand(ICommandExecutor executor) { commandMap.put(executor.getCommandName(), executor); } // 解析用户输入并执行命令 public String executeCommand(String input) { if (input == null || input.trim().isEmpty()) { return "错误:请输入有效命令"; } // 分割命令和参数(按空格分割,支持多参数) String[] parts = input.trim().split("\\s+"); String commandName = parts[0]; List<String> args = List.of(parts).subList(1, parts.length); // 查找对应的命令执行者 ICommandExecutor executor = commandMap.get(commandName); if (executor == null) { return "错误:未知命令:" + commandName; } return executor.execute(args); } }
4. 使用示例
public class Main { public static void main(String[] args) { CommandManager manager = new CommandManager(); // 注册所有命令 manager.registerCommand(new ExitCommand()); manager.registerCommand(new CreateRoomCommand()); // 测试不同命令 System.out.println(manager.executeCommand("exit")); System.out.println(manager.executeCommand("create_room 4")); System.out.println(manager.executeCommand("create_room")); // 参数不足的情况 System.out.println(manager.executeCommand("create_room abc")); // 参数格式错误的情况 } }
额外优化建议
- 可以给
ICommandExecutor接口添加getUsage()方法,返回命令的使用说明(比如"create_room <房间号>:创建指定ID的房间"),方便用户查看帮助; - 如果有大量带参数的命令,可以抽离通用的参数校验工具类,避免每个命令里重复写校验逻辑;
- 对于复杂参数(比如多个不同类型的参数),可以引入参数解析器,把字符串参数转换成对应的数据类型,让命令类更专注于业务逻辑。
内容的提问来源于stack exchange,提问作者riki
相关产品推荐
相关产品推荐

