当前实现是否符合策略模式?如何处理策略类代码重复?
策略模式合理性判断与代码重复优化方案
代码示例
@Service class MealService { private final List<MealStrategy> strategies; MealService(…) { this.strategies = strategies; } void handle() { var foo = …; var bar = …; strategies.forEach(s -> s.remove(foo, bar)); } }
现有BurgerStrategy和PastaStrategy两个策略类,均实现了MealStrategy接口的remove方法(接收两个参数)。其中BurgerStrategy负责从数据库获取枚举类型为burger的餐食并遍历执行操作,PastaStrategy逻辑类似,仅餐食类型不同。
一、当前实现命名为策略模式是否合理?
策略模式的核心是封装一组可替换的行为/算法,让调用方与具体实现解耦。你的实现虽然不是典型的“单一策略动态选择”场景(比如根据餐食类型选其中一个策略执行),但依然符合策略模式的核心设计思想:
- 把不同餐食的
remove业务逻辑(汉堡处理、意面处理)封装到独立的策略类中,与MealService解耦; - 策略类统一实现
MealStrategy接口,保证了调用的一致性; - 后续新增餐食类型(比如披萨),只需要新增对应的
PizzaStrategy,无需修改MealService的代码,完全符合开闭原则。
所以将其命名为策略模式是合理的,这属于策略模式的多策略批量执行变体,而非最常见的单策略选择场景。
二、两个策略类存在重复私有方法,是否应创建Helper类处理?
分两种场景讨论:
1. 重复方法是通用工具逻辑(与餐食业务无关)
如果重复的私有方法是无状态的通用工具逻辑(比如数据库查询的通用封装、集合遍历的通用处理、字符串格式化等),那么提取到独立的MealHelper类是合适的。这类方法职责单一,用Helper类可以避免代码重复,也便于其他业务模块复用。
2. 重复方法是餐食相关的业务逻辑
如果重复的方法是与餐食处理强相关的业务逻辑(比如“根据餐食类型查询数据”“遍历餐食执行操作的通用步骤”),更推荐抽象出父类(比如AbstractMealStrategy),将公共逻辑放到父类中,让BurgerStrategy和PastaStrategy继承该父类并实现差异化逻辑。
示例代码如下:
abstract class AbstractMealStrategy implements MealStrategy { // 公共方法:根据餐食类型查询数据 protected List<Meal> getMealsByType(MealType type) { // 通用数据库查询逻辑 } // 公共方法:遍历餐食执行操作的通用步骤 protected void processMeals(List<Meal> meals, Foo foo, Bar bar) { // 通用遍历处理逻辑 } } class BurgerStrategy extends AbstractMealStrategy { @Override public void remove(Foo foo, Bar bar) { var meals = getMealsByType(MealType.BURGER); processMeals(meals, foo, bar); // 汉堡特有的业务逻辑(如果有) } } class PastaStrategy extends AbstractMealStrategy { @Override public void remove(Foo foo, Bar bar) { var meals = getMealsByType(MealType.PASTA); processMeals(meals, foo, bar); // 意面特有的业务逻辑(如果有) } }
这种方式比Helper类更贴合面向对象设计,公共逻辑属于餐食策略的一部分,通过继承复用更符合业务语义,也便于后续扩展和维护。
内容的提问来源于stack exchange,提问作者Reddi
相关产品推荐
相关产品推荐

