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
- 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.
- Use the policy pattern when you have many similar classes that are only slightly different when performing certain behaviors.
- 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.
- 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…