SpringBoot,设计模式实践:策略模式

2,305 阅读3分钟

定义

策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。

策略模式适合应用场景

  1. 当你想使用对象中各种不同的算法变体, 并希望能在运行时切换算法时, 可使用策略模式。
  2. 当你有许多仅在执行某些行为时略有不同的相似类时, 可使用策略模式。
  3. 如果算法在上下文的逻辑中不是特别重要, 使用该模式能将类的业务逻辑与其算法实现细节隔离开来。
  4. 当类中使用了复杂条件运算符以在同一算法的不同变体中切换时, 可使用该模式。

实际场景需求

某系统存在用户,每个用户有对应的用户类型:消费者、工厂、代理商,现在需要为用户根据用户类型提供不同的服务。

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

}

8.测试结果如下:

image.png

image.png

参考文章:

juejin.cn/post/684490…

refactoringguru.cn/design-patt…