策略模式
简单来说就是告别代码中冗长的if/else,使不同的也不走不同的业务策略类,例如:电商支付场景等,有微信、支付宝、银联卡支付等等,不同的支付需要调用不同的SDK
恰巧最近在做组织机构结构改造的业务,考虑到后续业务可能多变,所以写代码时使用的策略模式。
接下来上代码:
- 书写基类接口,具体实现类均实现该接口(OrganResultDataStrategy)
- 组织机构策略类获取工厂(OrganSyncStructureFactory)
- 其他细节,编写传输上下文(OrganContextDTO)
- 也可以编写一个公共方法的父类,这样通用的功能直接super调用父类方法即可
下面的方法名自己可以灵活修改,主要是实现的方式
OrganResultDataStrategy接口
/**
* 组织机构结构改造处理基类 <br>
* 其他各种策略实现该接口
* <p>
* Date-Time: 2021/08/05 11:17
* </p>
* @Author fyan
* @Version 3.2.6
**/
public interface OrganResultDataStrategy {
/**
* 根据配置获取制定的结构
* 需要的参数 boolean start 是否进行组织机构结构修改, int level 修改到哪个层级之下, String strategy 具体的处理策略类名称
* @param strategy Organ config JSON 文件对象
* @return
*/
boolean transformType(JSONObject strategy);
/**
* 数据封装方法
* @param organContextDTO 组织机构数据传输上下文
* @return
*/
Object capsulation(final OrganContextDTO organContextDTO);
}
transformType方法是判断最终获取哪个实现类的方法,capsulation方法是具体的实现方法
OrganContextDTO上下文
/**
* @description: 组织机构结构修改数据传输上下文 .<br>
* <p>
* @DateTime: 2021-08-05 14:28
* </p>
* @Author fyan
* @Version
**/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class OrganContextDTO {
// 最终导出的数据
ExportOrgan exportOrgan;
// 组织机构原始数据,用于获取根节点或者父节点信息等
List<IBaseOrgan> organList;
}
参数封装你们业务所需要的实体类即可
OrganSyncStructureFactory接口
/**
* 组织机构处理策略工厂类. <br>
* 根据制定的策略获取制定的处理方式
* <p>
* Date-Time: 2021/08/05 11:15
* </p>
* @Author fyan
* @Version 3.2.6
**/
public final class OrganSyncStructureFactory {
private OrganSyncStructureFactory(){
throw new IllegalStateException("Utility class");
}
public static OrganResultDataStrategy getResultData(JSONObject strategy){
Map<String, OrganResultDataStrategy> beansOfType = SpringUtils.getBeansOfType(OrganResultDataStrategy.class);
for (Map.Entry<String, OrganResultDataStrategy> entry : beansOfType.entrySet()) {
OrganResultDataStrategy value = entry.getValue();
if (value.transformType(strategy)){
return value;
}
}
return null;
}
}
需要搭配Spring的上下文来实现具体实现类的获取
可以编写成工具类,也可以直接使用Spring上下文进行操作
public final class SpringUtils {
private SpringUtils(){}
private static ApplicationContext applicationContext;
public static void setApplicationContext(ApplicationContext context){
applicationContext = context;
}
public static <T> T getBean(Class<T> requiredType){
return applicationContext.getBean(requiredType);
}
public static <T> T getBean(String beanName, Class<T> beanType){
return applicationContext.getBean(beanName,beanType);
}
public static Object getBean(String beanName){
return applicationContext.getBean(beanName);
}
public String get(String key) {
return getBean(Environment.class).getProperty(key);
}
public static <T> Collection<T> getBeans(Class<T> type) {
Map<String, T> beans = applicationContext.getBeansOfType(type);
return beans.values();
}
public static <T> Map<String, T> getBeansOfType(Class<T> baseType) {
return applicationContext.getBeansOfType(baseType);
}
}
main方法下添加代码:
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(YdxcXcywApplication.class, args);
// 添加下面这段
SpringUtils.setApplicationContext(context);
}
OrganDataDeal类
最终实现类均继承该类,用于实现公共的功能。
/**
* @description: 涉及公共的数据处理类 .<br>
* <p>
* @DateTime: 2021-08-05 13:55
* </p>
* @Author fengyan
* @Version 3.2.6
**/
@Component
@Slf4j
public class OrganDataDeal {
@Autowired
private IOrganService organService;
/**
* 父类管理处理方法,用于处理获取所有省级下,所有的子单位、部门
* @return
*/
Map<String,String> getSuperStructureMap(){
return null;
}
}
实现类(NormalOrganResultDataStrategy、SuperCChangeOrganResultDataStrategy)
接下来是实现的具体策略类
/**
* 正常的组织机构数据结构,不需要任何处理.<br>
* <p>
* Date-Time: 2021/08/05 13:43
* </p>
* @Author fyan
* @Version 3.2.6
**/
@Component
@Slf4j
public class NormalOrganResultDataStrategy extends OrganDataDeal implements OrganResultDataStrategy{
public static final String STRATEGY = "normal";
@Override
public boolean transformType(JSONObject strategy) {
JSONObject changeStructure = strategy.getJSONObject(OrganSyncFieldEnum.CHANGESTRUCTURE.getCode());
String normal = Objects.toString(changeStructure.get(OrganSyncFieldEnum.STRATEGY.getCode()));
return StringUtils.equalsAnyIgnoreCase(STRATEGY, normal);
}
@Override
public Object capsulation(final OrganContextDTO organContextDTO) {
// 不做任何处理
return organContextDTO;
}
}
/**
* @description: 修改机构、部门、人员等部分父类ID信息 .<br>
* <p>
* @DateTime: 2021-08-05 13:50
* </p>
* @Author fengyan
* @Version 3.2.6
**/
@Component
@Slf4j
public class SuperCChangeOrganResultDataStrategy extends OrganDataDeal implements OrganResultDataStrategy{
public static final String STRATEGY = "SuperStructureChange";
public static JSONObject CONFIG;
@Override
public boolean transformType(JSONObject strategy) {
CONFIG = strategy;
JSONObject changeStructure = strategy.getJSONObject(OrganSyncFieldEnum.CHANGESTRUCTURE.getCode());
String superStructureChange = Objects.toString(changeStructure.get(OrganSyncFieldEnum.STRATEGY.getCode()));
return StringUtils.equalsAnyIgnoreCase(STRATEGY, superStructureChange);
}
@Override
public Object capsulation(final OrganContextDTO organContextDTO) {
// 映射关系,重新处理后的父类与子类关系
Map<String, String> superStructureMap = super.getSuperStructureMap();
// 导出的数据
// 处理单位
// 处理部门
// 清理资源
return organContextDTO;
}
}
调用
// 处理导出的组织机构
JSONObject strategy = organSyncConfigCache.get();
OrganResultDataStrategy resultData = OrganSyncStructureFactory.getResultData(strategy);
OrganContextDTO organContextDTO = OrganContextDTO
.builder()
.exportOrgan(exportOrgan)
.organList(organList)
.build();
resultData.capsulation(organContextDTO);
总结
主要就是策略的选择,只需要制定规则,就可以通过具体的标识选择指定的策略,并且每次修改也不用担心影响其他的功能。
方法中的参数都是可以根据自己的业务作出的修改,我这里使用JSONObject是因为业务需求用它比较方便,最好使用POJO类或者String,方便别人看你的代码。
有问题留言,看到会回复。