栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring实现策略模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring实现策略模式

什么是策略模式

指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法
在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护
如我最近写的爬虫小说,行为是爬取小说内容,但是针对不同的网站,实现都不一样
本文利用spring和java的新特性,整理了策略模式的两种实现方式

本文收获

1.java8的lambda
2.spring的aware接口
3.策略模式

实现方式 方式一:

1.定义接口和实现类,给每个不同的实现类指定key

public interface TestProxy {

    public String getTestKey();

    public void operate(Map param) throws IOException;

}
@Component
public class TestProxyImpl implements TestProxy {
    @Override
    public String getTestKey() {
        return "test1";
    }

    @Override
    public int[] operate(int[] arr) {
        System.out.println("我是快速排序算法");
        return arr;
    }
}
@Component
public class Test2ProxyImpl implements TestProxy {
    @Override
    public String getTestKey() {
        return "test2";
    }

    @Override
    public int[] operate(int[] arr) {
        System.out.println("我是选择排序算法");
        return arr;
    }
}

2.实现Aware接口,并通过map关联存储key和策略对象

@Component
public class TestFactory implements ApplicationContextAware {
    private Map beanMap;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //获取指定接口的实现类
        Map map = applicationContext.getBeansOfType(TestProxy.class);
        this.beanMap = new HashMap<>(map.size());
        map.forEach((k, v) -> this.beanMap.put(v.getBookEnum().name(), v));
    }

    
    public  T getTestProxy(String code) {
        return (T)this.beanMap.get(code);
    }
}

3.通过key动态选择策略

    @GetMapping({"/testStrategy/{key}"})
    @ApiOperation(value = "测试接口", notes = "test")
    public void testStrategy(@PathVariable("key") String key) throws Exception {
        TestProxy testProxy = testFactory.getTestProxy(key);
        int[] arr = new int[]{5,1,2,3,4};
        int[] result = testProxy.operate(arr);
        System.out.println(result);
    }
方式二:

1.定义策略

public interface ITestService {

    String method1(Map map);

    String method2(Map map);

    String method3(Map map);

}

2.通过Function函数存储策略

@Service
public class NewStrategy {

    @Autowired
    private ITestService iTestService;
    private static final Map, String>> GRANT_TYPE_MAP =new HashMap<>();

    
    @PostConstruct
    public void newStrategy(){
        GRANT_TYPE_MAP.put("method1",v->iTestService.method1(v));
        GRANT_TYPE_MAP.put("method2",v->iTestService.method2(v));
        GRANT_TYPE_MAP.put("method3",v->iTestService.method3(v));
    }

    public static String getResult(String key, Map param){
        //根据key获取具体的策略
        Function, String> result = GRANT_TYPE_MAP.get(key);
        if(result!=null){
            //传入参数执行方法体
            return result.apply(param);
        }
        return null;
    }

}

3.通过key动态选择策略

    @PostMapping ({"/getResult/{type}"})
    @ApiOperation(value = "测试策略活动的新玩法", notes = "test")
    @ResponseBody
    public String getResult(@RequestBody Map param, @PathVariable("type") String type) {
        return NewStrategy.getResult(type, param);
    }
两者区别

1.细粒度不同,前者以对象为单位,每一个新的策略都需要定义key和实现接口,后者只需关注策略方法即可

2.技术性不同,前者通过spring的Aware接口玩法实现,后者通过java的lambda函数式编程实现

题外话

Aware是spring系列一个比较常用的接口,用它可以实现一些方便的操作
如获取对象,获取当前环境

@Component
public class BeanFactory implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        BeanFactory.context = applicationContext;
    }

    
    public static   T getBean(Class className) {
        return context.getBean(className);
    }

    
    public static String getActiveProfile() {
        return context.getEnvironment().getActiveProfiles()[0];
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/854397.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号