狗日的老板今天看到我的代码又说我的代码质量差,说我的代码里遍地都是if else
public String work(String peopleType){
if ("学生".equals(peopleType)){
return "学生工作是上学";
}
if ("老师".equals(peopleType)){
return "老师工作是教课";
}
if ("牛马".equals(peopleType)){
return "牛马的工作是上班";
}
return "没有这个工作";
}
然后我就想到了另一种方法成功的把ifelse给去掉了,没想到老板还是鸡蛋壳里挑骨头
public String work(String peopleType) {
switch (peopleType) {
case "学生":
return "学生工作是上学";
case "老师":
return "老师工作是教课";
case "牛马":
return "牛马的工作是上班";
default:
return "没有这个工作";
}
}
于是我就上网查啊查,终于找到了一种可以代替if else的方式:策略模式
首先定义一个接口:
/**
* @author jerry
*/
public interface PeopleStrategy {
String work();
}
然后不同的人实现这个接口并实现work方法:
/**
* 学生策略类
*
* @author jerry
*/
public class StudentStrategy implements PeopleStrategy {
@Override
public String work() {
return "学生工作是上学";
}
}
/**
* 学生策略类
*
* @author jerry
*/
public class TeacherStrategy implements PeopleStrategy {
@Override
public String work() {
return "老师工作是教课";
}
}
/**
* CattleStrategy 牛马策略类
*
* @author jerry
* @date 2025/7/17 19:06
*/
public class CattleStrategy implements PeopleStrategy{
@Override
public String work() {
return "牛马的工作是上班";
}
}
为了使代码看起来更加优雅再给老板加个枚举类:
/**
* @author Jerry
*/
@Getter
public enum PeopleTypeEnum {
Teacher("老师"),
Student("学生"),
Cattle("牛马");
PeopleTypeEnum(String peopleType) {
this.peopleType = peopleType;
}
private final String peopleType;
}
最后再搞一个工厂类:
/**
* @author Jerry
* @description: 人员工厂类
*/
public class WorkerFactory {
private static Map<String, PeopleStrategy> accountStrategyMap;
public static String work(String peopleType) {
//简单模拟bean初始化 如果账号策略类为空 则初始化策略类数据
if (accountStrategyMap == null){
accountStrategyMap = new HashMap<>();
accountStrategyMap.put(PeopleTypeEnum.Student.getPeopleType(), new StudentStrategy());
accountStrategyMap.put(PeopleTypeEnum.Teacher.getPeopleType(), new TeacherStrategy());
accountStrategyMap.put(PeopleTypeEnum.Cattle.getPeopleType(), new CattleStrategy());
}
//根据人员类型获取不同账号的策略类
PeopleStrategy accountStrategy = accountStrategyMap.get(peopleType);
if (accountStrategy != null) {
return accountStrategy.work();
}
//获取不同账号的策略类组装参数
return "啥也不是";
}
}
最后看一下运行结果:
为了方便演示效果,在这里我使用了方法里面调用了map的put方法手动将每个策略类添加到了map中,在实际的项目开发中可以将这一操作放到bean的初始化时候自动执行,在 Spring 框架中,InitializingBean 是一个接口,其作用是在 Bean 初始化阶段执行特定逻辑。实现 InitializingBean 接口的类会在 Spring 容器完成 Bean 的属性设置后自动调afterPropertiesSet() 方法。
/**
* @author Jerry
* @description: 人员工厂类
*/
public class WorkerFactory implements InitializingBean {
private static Map<String, PeopleStrategy> accountStrategyMap;
public static String work(String peopleType) {
//根据人员类型获取不同账号的策略类
PeopleStrategy accountStrategy = accountStrategyMap.get(peopleType);
if (accountStrategy != null) {
return accountStrategy.work();
}
//获取不同账号的策略类组装参数
return "啥也不是";
}
@Override
public void afterPropertiesSet() throws Exception {
accountStrategyMap = new HashMap<>();
accountStrategyMap.put(PeopleTypeEnum.Student.getPeopleType(), new StudentStrategy());
accountStrategyMap.put(PeopleTypeEnum.Teacher.getPeopleType(), new TeacherStrategy());
accountStrategyMap.put(PeopleTypeEnum.Cattle.getPeopleType(), new CattleStrategy());
}
}
代码加了一大堆,得到的结果却是一样的。
最后,总结一下老板是狗日的,代码是优雅的。
优点
-
符合开闭原则(OCP)
-
新增策略时无需修改原有代码,只需添加新策略类,扩展性更好。
-
避免因需求变更频繁修改
if-else
分支,降低引入错误的风险。
-
-
代码结构更清晰
-
将不同逻辑拆分到独立的策略类中,减少单个类的复杂度。
-
消除冗长的
if-else
或switch-case
语句,提升可读性。
-
-
便于复用和维护
-
策略类可以独立测试、复用或组合(如通过依赖注入)。
-
逻辑变更时只需修改对应策略类,不影响其他代码。
-
-
解耦逻辑与上下文
-
上下文类(Context)只需关注策略的执行,不关心具体实现细节。
-
缺点
-
增加类的数量
-
每个策略需要一个单独类,可能导致类爆炸(尤其是简单逻辑时),反而增加复杂度。
-
-
适用于复杂场景
-
简单逻辑(如仅2-3个分支)时,策略模式可能显得“过度设计”,
if-else
更直接。
-
适用场景建议
-
推荐使用策略模式:
分支逻辑复杂、需频繁扩展或复用,或未来可能动态切换行为(如支付方式、算法选择等)。 -
保持
if-else
:
分支简单、稳定不变,或逻辑仅用于局部且无需复用的场景。