在写业务代码的时候,难免会遇到很多if-else,这个时候如果if-else不是很多可以用if-else。如果此时场景过多,太多的if-else会导致代码比较臃肿,所以这个时候就需要抽象化,将每个场景独立开来,定义一个顶层接口,不同场景有不同实现,这个时候策略模式就出现了。本文主要阐述工作中常用的实现策略模式的几种方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.ljm.service;
import com.ljm.constant.StrategyEnum;
/** * @Author: ljm * @Date: 2024/4/29 15:09 * @Version: v1.0.0 * @Description: TODO **/ public interface IHandler {
void handler(); StrategyEnum getHandleStrategy(); } |
1 2 3 4 5 6 7 8 9 10 11 |
package com.ljm.constant;
/** * @Author: ljm * @Date: 2024/4/29 15:10 * @Version: v1.0.0 * @Description: TODO **/ public enum StrategyEnum { FIRST, SECOND, THIRD, FOUR } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import com.ljm.constant.StrategyEnum; import com.ljm.service.IHandler; import org.springframework.stereotype.Service;
/** * @Author: ljm * @Date: 2024/4/29 15:12 * @Version: v1.0.0 * @Description: TODO **/ @Service public class FirstHandler implements IHandler {
@Override public void handler() { System.out.println("Execute First Handler"); }
@Override public StrategyEnum getHandleStrategy() { return StrategyEnum.FIRST; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.ljm.service.impl;
import com.ljm.constant.StrategyEnum; import com.ljm.service.IHandler; import org.springframework.stereotype.Service;
/** * @Author: ljm * @Date: 2024/4/29 15:12 * @Version: v1.0.0 * @Description: TODO **/ @Service public class SecondHandler implements IHandler { @Override public void handler() { System.out.println("Execute Second Handler"); }
@Override public StrategyEnum getHandleStrategy() { return StrategyEnum.SECOND; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.ljm.service.impl;
import com.ljm.constant.StrategyEnum; import com.ljm.service.IHandler; import org.springframework.stereotype.Service;
/** * @Author: ljm * @Date: 2024/4/29 15:12 * @Version: v1.0.0 * @Description: TODO **/ @Service public class ThirdHandler implements IHandler { @Override public void handler() { System.out.println("Execute Third Handler"); }
@Override public StrategyEnum getHandleStrategy() { return StrategyEnum.THIRD; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package com.ljm.service.impl;
import com.ljm.constant.StrategyEnum; import com.ljm.service.IHandler; import org.springframework.stereotype.Service;
/** * @Author: ljm * @Date: 2024/4/29 15:12 * @Version: v1.0.0 * @Description: TODO **/ @Service public class FourHandler implements IHandler { @Override public void handler() { System.out.println("Execute Four Handler"); }
@Override public StrategyEnum getHandleStrategy() { return StrategyEnum.FOUR; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package com.ljm.service;
import com.ljm.constant.StrategyEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import java.util.List; import java.util.concurrent.ConcurrentHashMap;
/** * @Author: ljm * @Date: 2024/4/29 15:16 * @Version: v1.0.0 * @Description: TODO **/ @Service public class HandlerStrategyFactory {
public final ConcurrentHashMap<StrategyEnum,IHandler> handlerStrategyMap = new ConcurrentHashMap<>();
@Autowired public HandlerStrategyFactory(List<IHandler> iHandlers){ iHandlers.forEach(x -> handlerStrategyMap.put(x.getHandleStrategy(),x)); }
public IHandler getHandleStrategy(StrategyEnum strategyEnum){ return handlerStrategyMap.get(strategyEnum); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.ljm;
import com.MyApplication; import com.ljm.constant.StrategyEnum; import com.ljm.service.HandlerStrategyFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/** * @Author: ljm * @Date: 2024/2/26 10:58 * @Version: v1.0.0 * @Description: TODO **/ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = MyApplication.class) public class MyTest {
@Autowired private HandlerStrategyFactory handlerStrategyFactory;
@Test public void testStrategy() { handlerStrategyFactory.getHandleStrategy(StrategyEnum.FIRST).handler(); handlerStrategyFactory.getHandleStrategy(StrategyEnum.SECOND).handler(); handlerStrategyFactory.getHandleStrategy(StrategyEnum.THIRD).handler(); handlerStrategyFactory.getHandleStrategy(StrategyEnum.FOUR).handler();
/* 测试结果 Execute First Handler Execute Second Handler Execute Third Handler Execute Four Handler*/ }
} |
实现一主要是为IHandler接口新增一个用于区分使用何种策略的方法,再构建一个策略工厂类,利用构造器注入的方式,将Spring中的实现类与相应的枚举类绑定,在使用的时候只需要传入StrategyEnum相应的值就可以调用想调用的策略.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com.ljm.service;
import com.ljm.constant.StrategyEnum; import org.springframework.beans.factory.InitializingBean;
/** * @Author: ljm * @Date: 2024/4/29 15:09 * @Version: v1.0.0 **/ public abstract class AbstractHandler implements InitializingBean {
public abstract void handler(); public abstract StrategyEnum getHandleStrategy();
@Override public void afterPropertiesSet() throws Exception { HandlerStrategyFactory.registerHandlerStrategy(this); } } |
1 2 3 4 5 6 7 8 9 10 11 |
package com.ljm.constant;
/** * @Author: ljm * @Date: 2024/4/29 15:10 * @Version: v1.0.0 * @Description: TODO **/ public enum StrategyEnum { FIRST, SECOND, THIRD, FOUR } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package com.ljm.service.impl;
import com.ljm.constant.StrategyEnum; import com.ljm.service.AbstractHandler; import org.springframework.stereotype.Service;
/** * @Author: ljm * @Date: 2024/4/29 15:12 * @Version: v1.0.0 * @Description: TODO **/ @Service public class FirstHandler extends AbstractHandler {
@Override public void handler() { System.out.println("Execute First Handler"); }
@Override public StrategyEnum getHandleStrategy() { return StrategyEnum.FIRST; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.ljm.service.impl;
import com.ljm.constant.StrategyEnum; import com.ljm.service.AbstractHandler; import org.springframework.stereotype.Service;
/** * @Author: ljm * @Date: 2024/4/29 15:12 * @Version: v1.0.0 * @Description: TODO **/ @Service public class SecondHandler extends AbstractHandler { @Override public void handler() { System.out.println("Execute Second Handler"); }
@Override public StrategyEnum getHandleStrategy() { return StrategyEnum.SECOND; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.ljm.service.impl;
import com.ljm.constant.StrategyEnum; import com.ljm.service.AbstractHandler; import org.springframework.stereotype.Service;
/** * @Author: ljm * @Date: 2024/4/29 15:12 * @Version: v1.0.0 * @Description: TODO **/ @Service public class ThirdHandler extends AbstractHandler { @Override public void handler() { System.out.println("Execute Third Handler"); }
@Override public StrategyEnum getHandleStrategy() { return StrategyEnum.THIRD; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package com.ljm.service.impl;
import com.ljm.constant.StrategyEnum; import com.ljm.service.AbstractHandler; import org.springframework.stereotype.Service;
/** * @Author: ljm * @Date: 2024/4/29 15:12 * @Version: v1.0.0 * @Description: TODO **/ @Service public class FourHandler extends AbstractHandler { @Override public void handler() { System.out.println("Execute Four Handler"); }
@Override public StrategyEnum getHandleStrategy() { return StrategyEnum.FOUR; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.ljm.service;
import com.ljm.constant.StrategyEnum;
import java.util.concurrent.ConcurrentHashMap;
/** * @Author: ljm * @Date: 2024/4/29 15:16 * @Version: v1.0.0 * @Description: TODO **/ public class HandlerStrategyFactory {
public static final ConcurrentHashMap<StrategyEnum, AbstractHandler> handlerStrategyMap = new ConcurrentHashMap<>();
public static void registerHandlerStrategy(AbstractHandler handler) { handlerStrategyMap.put(handler.getHandleStrategy(), handler); }
public static AbstractHandler getHandleStrategy(StrategyEnum strategyEnum) { return handlerStrategyMap.get(strategyEnum); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package com.ljm;
import com.MyApplication; import com.ljm.constant.StrategyEnum; import com.ljm.service.HandlerStrategyFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/** * @Author: ljm * @Date: 2024/2/26 10:58 * @Version: v1.0.0 * @Description: TODO **/ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = MyApplication.class) public class MyTest {
@Test public void testStrategy() { HandlerStrategyFactory.getHandleStrategy(StrategyEnum.FIRST).handler(); HandlerStrategyFactory.getHandleStrategy(StrategyEnum.SECOND).handler(); HandlerStrategyFactory.getHandleStrategy(StrategyEnum.THIRD).handler(); HandlerStrategyFactory.getHandleStrategy(StrategyEnum.FOUR).handler();
/* 测试结果 Execute First Handler Execute Second Handler Execute Third Handler Execute Four Handler*/ }
} |
实现二主要是为AbstractHandler抽象类实现InitializingBean接口,再对象初始化的时候将其注册到我们自己构建的策略工厂类中,此时的对象由Spring生成并与相应的枚举类绑定,在使用的时候只需要传入StrategyEnum相应的值就可以调用想调用的策略.