使用Factory模式创建经典迪士尼剧情工厂的实现正确性及方法咨询
问题诊断:现有Factory模式应用的问题
你当前的写法属于工厂方法的初始思路,但存在多处错误和不合理设计:
- 类型匹配错误:入参是
Character类型,直接和字符串常量做equals比对永远返回false,核心逻辑完全无法触发 - 违反开闭原则:硬编码的多分支
if-else结构,后续新增剧情工厂时必须修改当前方法,可维护性差 - 缺少边界校验:未处理入参为null的场景,调用
equals会直接抛出空指针异常 - 缺少默认返回分支:当前代码所有条件都不满足时无返回值,编译无法通过
正确实现方案
第一步:先定义基础依赖
首先明确PlotFactory抽象接口,以及对应不同经典迪士尼剧情的实现类,示例如下:
// 抽象剧情工厂接口 public interface PlotFactory { Plot generate(); // 生成具体剧情的方法 } // 示例:狮子王剧情工厂实现 public class LionKingPlotFactory implements PlotFactory { @Override public Plot generate() { // 实现狮子王的经典剧情生成逻辑 return new LionKingPlot(); } } // 示例:冰雪奇缘剧情工厂实现 public class FrozenPlotFactory implements PlotFactory { @Override public Plot generate() { return new FrozenPlot(); } }
你可以按照这个结构实现所有你需要的经典迪士尼剧情对应的工厂类。
第二步:重构工厂获取方法
用预加载的映射表替代硬编码if-else,同时修复参数校验问题:
如果使用Java 16以下版本,可自行实现静态类
CharacterTriple,重写equals和hashCode方法即可,功能和record完全一致。
// 首先定义三元组作为映射的key,重写equals和hashCode保证匹配正确 private record CharacterTriple(Character hero, Character another, Character without) {} // 预加载所有剧情工厂的映射关系,初始化仅执行一次 private static final Map<CharacterTriple, PlotFactory> PLOT_FACTORY_MAP = Map.of( new CharacterTriple('A', 'B', 'C'), new LionKingPlotFactory(), new CharacterTriple('D', 'E', 'F'), new FrozenPlotFactory(), new CharacterTriple('G', 'H', 'I'), new LittleMermaidPlotFactory() // 后续新增剧情工厂仅需在此加映射即可,无需修改业务逻辑 ); public PlotFactory classicDisneyPlotFactory(Character hero, Character another, Character without) { // 先做入参非空校验 if (hero == null || another == null || without == null) { throw new IllegalArgumentException("所有角色参数不可为null"); } // 直接从映射表取对应工厂,无匹配可以返回默认工厂或者抛异常 CharacterTriple key = new CharacterTriple(hero, another, without); return PLOT_FACTORY_MAP.getOrDefault(key, new DefaultDisneyPlotFactory()); // 如果你需要无匹配时报错,可以替换为: // return PLOT_FACTORY_MAP.getOptional(key) // .orElseThrow(() -> new IllegalArgumentException("无匹配的迪士尼剧情工厂")); }
这个方案的优势:
- 符合开闭原则,新增剧情工厂无需修改方法逻辑,仅需新增映射配置
- 修复了原有的类型匹配bug,
Character类型和字符常量比对逻辑正确 - 有完善的入参校验,避免空指针异常
- 查找逻辑时间复杂度为O(1),比多分支
if-else效率更高 - 所有映射关系集中管理,可维护性更强
内容的提问来源于stack exchange,提问作者Petru Ciorba
相关产品推荐
相关产品推荐

