define

The strategy pattern is a behavior design pattern that allows you to define a series of algorithms and place each algorithm in a separate class so that the objects of the algorithm are interchangeable.

The policy mode is suitable for application scenarios

  1. Use policy mode when you want to work with various algorithm variants in an object and want to be able to switch algorithms at runtime.
  2. Use the policy pattern when you have many similar classes that are only slightly different when performing certain behaviors.
  3. If the algorithm is not particularly important in the logic of the context, this pattern can be used to isolate the business logic of the class from its algorithm implementation details.
  4. This pattern can be used when complex conditional operators are used in a class to switch between variations of the same algorithm.

Actual scenario requirements

A system has users, and each user has a corresponding user type: consumer, factory, and agent. Now the system needs to provide different services for users according to the user type.

1. Create an enumeration of user types

/** * user type enumeration * @author */ public enum UserTypeEnum {PROXY(" PROXY "), CUSTOMER(" CUSTOMER "), FACTORY(" FACTORY "); private String userType; UserTypeEnum(String userType) { this.userType = userType; }}Copy the code

2. Create a user entity

@Data public class User { String name; // Name String userType; // Type, public User(String name, String userType) {this.name = name; this.userType = userType; }}Copy the code

3. Create the UserService interface UserService

public interface UserService { String Service(User user); // User services}Copy the code

4. Create three IMPLS to implement userService and InitializingBean interface

Description: CustomerServiceImpl, ProxyServiceImpl, and FactoryServiceImpl correspond to the InitializingBean interface provided by the Spring service corresponding to the three user types respectively. This interface provides a method for Bean property initialization, and any class that inherits this interface executes this method after Bean property initialization.

@Service public class CustomerServiceImpl implements UserService,InitializingBean { @Override public String Service(User User) {return "user type: "+user.getUserType()+", can get consumer service "; } @Override public void afterPropertiesSet() throws Exception { UserServiceStrategyFactory.register(UserTypeEnum.CUSTOMER.name(),this); // Register Bean}}Copy the code
@Service public class FactoryServiceImpl implements UserService,InitializingBean { @Override public String Service(User User) {return "user type: "+user.getUserType()+", can get factory service "; } @Override public void afterPropertiesSet() throws Exception { UserServiceStrategyFactory.register(UserTypeEnum.FACTORY.name(),this); }}Copy the code
@Service public class ProxyServiceImpl implements UserService,InitializingBean { @Override public String Service(User User) {return "user type: "+user.getUserType()+"; } @Override public void afterPropertiesSet() throws Exception { UserServiceStrategyFactory.register(UserTypeEnum.PROXY.name(),this); }}Copy the code

5. Create a policy Factory class to hold the policy class instance (the three IMPLs from Step 4)

Class description: defines a Map to store all instances of the policy class, and provides a getByUserType method, can directly obtain the corresponding class instances according to the type. There is also a register method for registering beans, used in the three IMPLs of Step 4

public class UserServiceStrategyFactory { private static Map<String,UserService> services = new ConcurrentHashMap<String,UserService>(); Public static UserService getByUserType(String userType){return services.get(userType); } public static void register(String userType,UserService userPayService){ services.put(userType,userPayService); }}Copy the code

6. Create UserServiceImpl to implement Uservice, which integrates the other three IMPL functions

@Service public class UserServiceImpl implements UserService{ @Override public String Service(User user) { UserService byUserType = UserServiceStrategyFactory.getByUserType(user.getUserType()); return byUserType.Service(user); }}Copy the code

7. Create a new Controller for testing

@RestController public class UserController { @Qualifier("userServiceImpl") @Autowired UserService userService; @GetMapping("/userType") public String userType(User user){ return userService.Service(user); }}Copy the code

8. The test results are as follows:

Reference article:

Juejin. Cn/post / 684490…

Refactoringguru. Cn/design – patt…