Ruby CLI国际象棋项目:错误处理策略选型咨询
Ruby CLI国际象棋游戏错误处理策略
在开发CLI国际象棋游戏时,针对输入格式校验、棋子移动规则验证等不同场景,错误处理的策略选择要贴合场景需求,以下结合你的代码示例逐一说明:
1. 交互式用户输入格式校验:用循环/递归重试替代异常
对于CLI中需要用户即时纠正输入格式的场景(比如你写的get_move流程),直接用循环或递归引导用户重新输入是更合适的方案。这种场景下,输入错误是预期内的流程分支,而非意外错误,不需要抛出异常增加复杂度。
你的实现示例已经很贴合这个场景:
def get_move # 获取用户输入的逻辑... return rescue_invalid_format_error(move) unless chess_format?(move) # 后续处理逻辑... end def rescue_invalid_format_error(move) puts "你的移动指令 '#{move}' 格式错误,正确格式应为 'a1,a2',请重新输入..." get_move end
这种方式直接在流程内处理错误,用户体验更流畅,不需要中断程序再捕获异常。
2. 业务规则校验:用自定义异常类传递错误
当涉及到业务规则违规(比如棋子移动不符合规则、内部数据格式错误)时,自定义异常类是更好的选择。这类错误属于意外的非法操作,需要在调用栈的合适位置统一处理,而非在校验点直接处理。
你定义的InputError是正确的方向,但注意:自定义异常不会自动处理,必须在调用处用begin-rescue块捕获,否则会导致程序崩溃。
自定义异常类示例:
# input_errors.rb class InputError < StandardError def initialize(message = '输入错误') super(message) end end
抛出异常的业务方法:
def add_move(indexed_move) if index_format?(indexed_move) true_move?(indexed_move) ? @moves << indexed_move : (raise InputError.new("指令 #{indexed_move} 不是合法的棋子移动")) else raise InputError.new("索引格式错误,#{indexed_move} 应符合 'iiii' 格式") end end
调用时捕获异常:
begin add_move(processed_move) rescue InputError => e puts e.message # 这里可以选择重试、回滚操作或终止当前流程 end
用异常的好处是可以将错误处理逻辑和业务逻辑解耦,比如在游戏主循环中统一捕获所有InputError并提示用户,不用在每个校验方法里重复写提示代码。
3. 其他可选策略:返回结果元组
如果不想用异常,还可以让校验方法返回包含状态和数据的元组,比如[:success, 结果]或[:failure, 错误信息]。这种方式适合简单场景,避免异常带来的调用栈开销:
def validate_move(indexed_move) return [:failure, "索引格式错误"] unless index_format?(indexed_move) return [:failure, "不是合法移动"] unless true_move?(indexed_move) [:success, indexed_move] end # 调用时 result = validate_move(move) if result[0] == :failure puts result[1] else @moves << result[1] end
但这种方式在复杂调用栈中会导致每层都要判断返回状态,不如异常的统一处理高效。
总结场景选择
- 交互式输入纠正:优先用循环/递归重试,直接引导用户修正输入,属于流程内的预期处理。
- 业务规则违规:用自定义异常类,将错误传递到上层统一处理,解耦业务逻辑和错误处理。
- 简单校验场景:可选返回结果元组,避免异常的复杂度。
内容的提问来源于stack exchange,提问作者jbk
相关产品推荐
相关产品推荐

