使用设计模式改写if/else或switch/case语句
在写代码的时候,经常会用到if/else语句或者switch/case语句。虽然很省事,但是没有体现到java的封装、继承、多态等特性。没有用到java的面向对象编程的精髓。
比如这种if/else语句:
1 2 3 4 5 6 7 8 9 10 | String str = "菠萝" ; if ( "苹果" .equals(str)) { System.out.println( "又大又红的苹果" ); } else if ( "菠萝" .equals(str)) { System.out.println( "又酸又甜的菠萝" ); } else if ( "梨" .equals(str)) { System.out.println( "又甜又脆的梨" ); } |
我们应该如何使用设计模式改写呢?
第一种方式:使用策略模式
接口:Strategy
1 2 3 | public interface Strategy { void comment(); } |
苹果实现类:
public class Apple implements Strategy { @Override public void comment() { System.out.println("又大又红的苹果"); } }
菠萝实现类:
public class Pineapple implements Strategy {
@Override
public void comment() {
System.out.println("又酸又甜的菠萝");
}
}
梨实现类:
public class Pear implements Strategy { @Override public void comment() { System.out.println("又甜又脆的梨"); } }
枚举类:

1 public enum FruitsEnum { 2 APPLE, PINEAPPLE, PEAR; 3 }
处理类:

1 public class People { 2 private static Map<FruitsEnum, Strategy> map; 3 4 static { 5 map = new HashMap(); 6 map.put(FruitsEnum.APPLE, new Apple()); 7 map.put(FruitsEnum.PINEAPPLE, new Pineapple()); 8 map.put(FruitsEnum.PEAR, new Pear()); 9 } 10 11 public static void commentFruit(FruitsEnum fruitEnum) { 12 for (Map.Entry<FruitsEnum, Strategy> entry : map.entrySet()) { 13 if (fruitEnum.equals(entry.getKey())) { 14 entry.getValue().comment(); 15 } 16 } 17 } 18 }
调用:
People.commentFruit(FruitsEnum.PINEAPPLE);
策略模式(Strategy Pattern)属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
其主要目的是通过定义相似的算法,替换if else 语句写法,并且可以随时相互替换。
策略模式主要由这三个角色组成,环境角色(Context)、抽象策略角色(Strategy)和具体策略角色(ConcreteStrategy)。
环境角色(Context):持有一个策略类的引用,提供给客户端使用。
抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
具体策略角色(ConcreteStrategy):包装了相关的算法或行为。
示例图如下:
相比传统的if/else语句,使用策略模式后代码体现出了面向对象的特性,扩展性更强,但是还是存在一些缺陷,需要一个map,而且需要new出每个实现类的实例。学过spring的都知道这样存在非常强的耦合性,这个时候可以用到spring ioc相关的知识点来改写。
第二种方式:策略模式+spring ioc(ApplicationObjectSupport)
接口:Strategy
public interface Strategy { void comment(); }
苹果实现类:
@Component public class Apple implements Strategy { @Override public void comment() { System.out.println("又大又红的苹果"); } }
菠萝实现类:
@Component public class Pineapple implements Strategy { @Override public void comment() { System.out.println("又酸又甜的菠萝"); } }
梨实现类:
@Component public class Pear implements Strategy { @Override public void comment() { System.out.println("又甜又脆的梨"); } }
枚举类:
public enum FruitEnum { APPLE("苹果", "apple"), PINEAPPLE("菠萝", "pineapple"), PEAR("梨", "pear"); private String name; private String desc; FruitEnum(String name, String desc) { this.name = name; this.desc = desc; } public String getName() { return name; } public String getDesc() { return desc; } public static FruitEnum find(String type) { FruitEnum fruitEnum = Arrays.stream(FruitEnum.values()).filter(f -> type.equals(f.getName())) .findFirst().orElse(null); return fruitEnum; } }
继承ApplicationObjectSupport:
@Service public class PeopleStrategyService extends ApplicationObjectSupport { public Strategy getInstance(String type) { return super.getApplicationContext().getBean(FruitEnum.find(type).getDesc(), Strategy.class); } }
处理类:
@Service public class PeopleService { @Autowired private PeopleStrategyService peopleStrategyService; public void peopleComment(String type) { peopleStrategyService.getInstance(type).comment(); } }
调用:
peopleService.peopleComment(FruitEnum.PINEAPPLE.getName());
这里主要用到策略模式和spring ioc相关的知识点。
1.ApplicationObjectSupport的知识点
2.@Component、@Service、@Autowired等注解的知识点
这种方式发挥了spring ioc的优点,解决了耦合性,但还不是最简洁的方式。
第三种方式:策略模式+spring ioc(InitializingBean)
接口:继承InitializingBean
public interface EventService extends InitializingBean { void handler(); }
苹果实现类:
@Service public class AppleEventServiceImpl implements EventService { @Override public void handler() { System.out.println("又大又红的苹果"); } @Override public void afterPropertiesSet() throws Exception { EventServiceFactory.register(FruitEnum.APPLE.getName(), this); } }
菠萝实现类:
@Service public class PineappleEventServiceImpl implements EventService { @Override public void handler() { System.out.println("又酸又甜的菠萝"); } @Override public void afterPropertiesSet() throws Exception { EventServiceFactory.register(FruitEnum.PINEAPPLE.getName(), this); } }
这里省略掉梨的实现类,大家可以自己去补充
枚举类也省略,大家自己去补充
处理类:
@Component public class EventServiceFactory { private static Map<String, EventService> EVENT_SERVICE_MAP = new ConcurrentHashMap<>(); public static EventService getHandler(String type) { return EVENT_SERVICE_MAP.get(type); } public static void register(String type, EventService eventService) { EVENT_SERVICE_MAP.put(type, eventService); } }
调用:
EventServiceFactory.getHandler(FruitEnum.APPLE.getName()).handler();
这里主要用到策略模式和spring ioc相关的知识点。
1.InitializingBean(afterPropertiesSet)的知识点
这种方式是我能想到的最简洁的方式了,同时解决了耦合性的问题。
当然也可以省略掉枚举类,switch/case的场景用枚举比较多,if/else的情况下可以不用枚举类,把变量放在对应的实现类里面即可。
好的,使用设计模式改写if/else或switch/case语句今天就写到这,大家有兴趣的可以在评论区回复交流。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现