Summary of several ways to implement the policy pattern in Spring _java_ Script home

Summary of several ways to implement policy patterns in Spring

Updated: May 01, 2024 08:04:41 Author: Le Jiaming
When writing business code, it is inevitable to encounter a lot of if-else, this time if the if-else is not a lot of you can use if-else, if there are too many scenes at this time, too much if-else will lead to code is bloated, this time the strategy pattern appears, this article mainly describes the work commonly used to achieve the strategy pattern of several ways, need Friends can refer to it

I. Background

When writing business code, it is inevitable to encounter a lot of if-else, this time if there is not a lot of if-else can use if-else. if there are too many scenes at this time, too many if-else will lead to bloated code, so at this time you need to abstract, separate each scene, define a top-level interface, different scenarios have different implementations, this time the strategy pattern appears. This paper mainly describes several ways to implement the policy pattern commonly used in the work.

Two. Implement one

2.1 Defining Interfaces

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();
}

2.2 Defining an Enumeration

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
}

2.3 Defining Implementation classes

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; }}
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; }}
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; }}
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; }}

2.4 Defining the policy factory class

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); }}

2.5 Testing

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(); /* Test result Execute First Handler Execute Second Handler Execute Third Handler Execute Four Handler*/}}

The main implementation is to add a new method for IHandler interface to distinguish which policies to use, and then build a policy factory class, using the constructor injection method, the Spring implementation class and the corresponding enumeration class binding, in use only need to pass the StrategyEnum corresponding value can call the policy you want to call.

Three. Achieve two

3.1 Defining Abstract classes

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); }}

3.2 Defining an Enumeration

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
}

3.3 Defining Implementation classes

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; }}
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; }}
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; }}
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; }}

3.4 Defining the policy Factory class

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); }}

3.5 Testing

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(); /* Test result Execute First Handler Execute Second Handler Execute Third Handler Execute Four Handler*/}}

The second implementation is to implement the InitializingBean interface for the AbstractHandler abstract class, and then register it into our own policy factory class during object initialization. At this time, the object is generated by Spring and bound with the corresponding enumeration class. In use, you only need to pass the corresponding value of StrategyEnum to invoke the desired policy.

The above is a summary of several ways to implement the policy pattern in Spring. For more information about Spring's implementation of the policy pattern, please pay attention to other related articles in Script Home!

Related article

Latest comments