Monopoly开发疑问:能否通过传递构造属性拆分Board类方法以符合SRP?
大富翁Board类职责拆分的实践建议
结论
方案2(将squares数组传入Board内部实例化的各职责类)是更符合SOLID原则的良好实践,能彻底解决Board类违反单一职责的问题,同时让代码更易维护、扩展和测试。
具体落地思路
- 按业务逻辑拆分专属类:把原Board中20-30个方法按领域归类:
PropertyGroupValidator:负责检查同组地产是否归属同一玩家、验证同组地产状态(比如建造房屋的前置条件)HouseManager:处理房屋的建造、拆除逻辑,依赖同组地产的状态MortgageHandler:管理地产抵押、解押的规则流程
- 重新定义Board的角色:Board不再做具体业务逻辑,只做三件事:
- 持有
squares数组的唯一引用 - 初始化上述职责类时,提供
squares的封装访问(而非直接传数组引用) - 对外暴露简化的入口方法,内部转发给对应职责类处理
- 持有
关键注意点
- 不要直接暴露
squares数组:给职责类提供封装好的查询方法,比如getPropertyGroup(int propertyIndex)、getOwnerProperties(Player player),避免外部类随意修改数组,同时降低耦合。 - 跨Square的逻辑统一处理:像“建造房屋需同组无抵押”这类依赖多个Square状态的逻辑,统一放在
PropertyGroupValidator中,由它通过Board的查询方法获取所需数据,职责更清晰。 - 保持职责类高内聚:每个类只管一块逻辑,比如
HouseManager只关心房屋相关规则,碰都不碰抵押或机会卡的逻辑。
为什么不选方案1
方案1会让Board类变成“万能工具类”,后续新增规则(比如加新的Square类型、调整房屋建造上限)时,只能不断往Board里塞方法,代码会越来越乱,测试和维护成本飙升。而方案2的每个职责类可以单独写单元测试,比如测试房屋建造逻辑时,只需要模拟一组地产的状态,不用初始化整个40个Square的Board,效率高得多。
内容的提问来源于stack exchange,提问作者Caleb
相关产品推荐
相关产品推荐

