如何优化Recommender类实现?避免null判断的if/else分支
优化推荐系统的Handler结果合并逻辑(消除if/else分支)
问题核心
当前Recommender类通过逐个判断UserPreferences中不同类型的info是否为null来合并结果,这种方式不仅冗余,还违反开闭原则——新增MovieHandler实现类时必须修改Recommender的判断逻辑。
解决方案:让Handler自治合并逻辑
给MovieHandler接口新增一个merge方法,让每个具体Handler负责自身类型的结果合并,彻底消除if/else分支。
1. 修改MovieHandler接口
public interface MovieHandler { // 生成对应类型的推荐内容 UserPreferences process(Context context, Customer customer, History history); // 将自身生成的部分结果合并到总结果中 void merge(UserPreferences totalPreferences, UserPreferences partialPreferences); }
2. 实现具体Handler的merge方法
以AdventureMovieHandler为例,其他Handler同理:
public class AdventureMovieHandler implements MovieHandler { @Override public UserPreferences process(Context context, Customer customer, History history) { // 原有逻辑:生成包含adventureInfo和对应movies的UserPreferences UserPreferences prefs = new UserPreferences(); prefs.setAdventureInfo(generateAdventureInfo(context, customer, history)); prefs.setMovies(generateAdventureMovies(context, customer, history)); return prefs; } @Override public void merge(UserPreferences total, UserPreferences partial) { // 仅合并自身类型的info,并追加movies列表 total.setAdventureInfo(partial.getAdventureInfo()); total.getMovies().addAll(partial.getMovies()); } }
3. 简化Recommender的getRecommendations方法
现在无需任何if/else判断,直接循环调用Handler的process和merge即可:
public class Recommender { private List<MovieHandler> movieHandlers; public UserPreferences getRecommendations(Context context, Customer customer, History history) { UserPreferences totalPrefs = new UserPreferences(); for (MovieHandler handler : movieHandlers) { UserPreferences partialPrefs = handler.process(context, customer, history); if (partialPrefs != null) { handler.merge(totalPrefs, partialPrefs); } } return totalPrefs; } // 构造方法、setter等省略 }
方案优势
- 彻底消除if/else:无需再判断哪个类型的
info非空,每个Handler只处理自己的逻辑 - 遵循开闭原则:新增
MovieHandler实现类时,只需实现接口的两个方法,无需修改Recommender代码 - 职责清晰:每个Handler既负责生成对应类型的推荐,也负责将结果合并到总对象中,符合单一职责原则
- 保持返回格式不变:最终返回的
UserPreferences结构完全符合原有要求,无需修改调用方逻辑
备选方案:集中式合并策略映射
如果希望合并逻辑集中管理,可以在Recommender中维护一个类型到合并逻辑的映射:
public class Recommender { private List<MovieHandler> movieHandlers; private Map<String, BiConsumer<UserPreferences, UserPreferences>> mergeStrategies; public Recommender() { mergeStrategies = new HashMap<>(); // 注册各类型的合并逻辑 mergeStrategies.put("adventure", (total, partial) -> { total.setAdventureInfo(partial.getAdventureInfo()); total.getMovies().addAll(partial.getMovies()); }); mergeStrategies.put("comedy", (total, partial) -> { total.setComedyInfo(partial.getComedyInfo()); total.getMovies().addAll(partial.getMovies()); }); // 其他类型同理 } public UserPreferences getRecommendations(Context context, Customer customer, History history) { UserPreferences totalPrefs = new UserPreferences(); for (MovieHandler handler : movieHandlers) { UserPreferences partialPrefs = handler.process(context, customer, history); if (partialPrefs != null && partialPrefs.getRecommendationType() != null) { BiConsumer<UserPreferences, UserPreferences> merger = mergeStrategies.get(partialPrefs.getRecommendationType()); if (merger != null) { merger.accept(totalPrefs, partialPrefs); } } } return totalPrefs; } }
这种方式需要给UserPreferences添加recommendationType字段来标识类型,适合合并规则需要统一调整的场景,但新增类型时需在Recommender中注册策略。
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

