定义
策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。
策略模式适合应用场景
- 当你想使用对象中各种不同的算法变体, 并希望能在运行时切换算法时, 可使用策略模式。
- 当你有许多仅在执行某些行为时略有不同的相似类时, 可使用策略模式。
- 如果算法在上下文的逻辑中不是特别重要, 使用该模式能将类的业务逻辑与其算法实现细节隔离开来。
- 当类中使用了复杂条件运算符以在同一算法的不同变体中切换时, 可使用该模式。
实际场景需求
某系统存在用户,每个用户有对应的用户类型:消费者、工厂、代理商,现在需要为用户根据用户类型提供不同的服务。
1. 新建用户类型枚举
/**
* 用户类型枚举
* @author 勤任风
*/
public enum UserTypeEnum {
PROXY("代理"),
CUSTOMER("消费者"),
FACTORY("工厂");
private String userType;
UserTypeEnum(String userType) {
this.userType = userType;
}
}
2. 新建用户实体
@Data
public class User {
String name; //名称
String userType; //类型,
public User(String name, String userType) {
this.name = name;
this.userType = userType;
}
}
3. 新建用户服务接口:UserService
public interface UserService {
String Service(User user); //用户服务
}
4. 新建三个Impl实现userService,并实现InitializingBean接口
说明:CustomerServiceImpl、ProxyServiceImpl、FactoryServiceImpl分别对应三种用户类型对应的服务 Spring种提供的InitializingBean接口,这个接口为Bean提供了属性初始化后的处理方法,凡是继承了该接口的类,在bean的属性初始化后都会执行该方法。
@Service
public class CustomerServiceImpl implements UserService,InitializingBean {
@Override
public String Service(User user) {
return "用户类型:"+user.getUserType()+",可以获得消费者服务";
}
@Override
public void afterPropertiesSet() throws Exception {
UserServiceStrategyFactory.register(UserTypeEnum.CUSTOMER.name(),this); //注册Bean
}
}
@Service
public class FactoryServiceImpl implements UserService,InitializingBean {
@Override
public String Service(User user) {
return "用户类型:"+user.getUserType()+",可以获得工厂服务";
}
@Override
public void afterPropertiesSet() throws Exception {
UserServiceStrategyFactory.register(UserTypeEnum.FACTORY.name(),this);
}
}
@Service
public class ProxyServiceImpl implements UserService,InitializingBean {
@Override
public String Service(User user) {
return "用户类型:"+user.getUserType()+",可以获得代理商服务";
}
@Override
public void afterPropertiesSet() throws Exception {
UserServiceStrategyFactory.register(UserTypeEnum.PROXY.name(),this);
}
}
5.新建策略工厂类, 用于保存策略类实例(即第4步骤的三个impl)
类说明:定义了一个Map,用来保存所有的策略类的实例,并提供一个getByUserType方法,可以根据类型直接获取对应的类的实例。还有一个register方法,用于注册Bean,在第4步骤的三个impl用到
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);
}
}
6. 新建UserServiceImpl实现Uservice,用于统合其他三个impl功能
@Service
public class UserServiceImpl implements UserService{
@Override
public String Service(User user) {
UserService byUserType = UserServiceStrategyFactory.getByUserType(user.getUserType());
return byUserType.Service(user);
}
}
7. 新建个Controller用于测试
@RestController
public class UserController {
@Qualifier("userServiceImpl")
@Autowired
UserService userService;
@GetMapping("/userType")
public String userType(User user){
return userService.Service(user);
}
}