• lambda表达式滥用之殇:解耦三层嵌套lambda表达式


    自从 Java8 支持 lambda 表达式, 代码中的 lambda 就到处都是。 但大多是滥用。

    lambda 表达式用于表达简短的逻辑(可以看做 C 语言的内联函数)非常清晰,但用来表达比较长的业务逻辑,就与其设计初衷背道而驰了。

    如下所示,三层嵌套 lambda 表达式,晕了没有 ?



    如何解开这些结呢 ? 一步步来。

    首先, allImageIds.forEach 是一个明显的 Stream-add 模式,可以使用 stream.map 来表达:

    List<CompletableFuture<String>> completableFutureList
                    = allImageIds.stream().map(imageId -> buildCompletableFuture(imageId, comId, newGroup)).collect(Collectors.toList());
    
        private CompletableFuture<String> buildCompletableFuture(String imageId, String comId, int newGroup) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                String lockKey = String.format("%s%s%s", comId, newGroup, imageId);
                return redisLock.call(lockKey, () -> {
                    return dealWith(comId, newGroup, imageId);
                });
            }, executorService);
            return future;
        }
    

    这样,就解耦了一层。


    接下来,CompletableFuture.supplyAsync 需要提供一个 Supplier , 可以把这个 lambda 提取出来:

        private CompletableFuture<String> buildCompletableFuture(String imageId, String comId, int newGroup) {
    
            Supplier<String> futureSupplier = () -> {
                String lockKey = String.format("%s%s%s", comId, newGroup, imageId);
                return redisLock.call(lockKey, () -> {
                    return dealWith(comId, newGroup, imageId);
                });
            };
    
            CompletableFuture<String> future = CompletableFuture.supplyAsync(futureSupplier, executorService);
            return future;
        }
    

    这样,我们又让结构清晰了一些。


    最后,我们把 redisLock.call 里面的 lambda 表达式分离出来。 这个 lambda 表达式代表的是 ValueLockCallback 接口。 可以把这个表达式变成一个内部类(还原) ImageIdValueCallback :

    
    private CompletableFuture<String> buildCompletableFuture(String imageId, String comId, int newGroup) {
     
        Supplier<String> futureSupplier = () -> {
            String lockKey = String.format("%s%s%s", comId, newGroup, imageId);
            return redisLock.call(lockKey, new ImageIdValueCallback(imageId, comId, newGroup));
        };
     
        CompletableFuture<String> future = CompletableFuture.supplyAsync(futureSupplier, executorService);
        return future;
    }
    
        class ImageIdValueCallback implements ValueLockCallback<String> {
    
            private String imageId;
            private String comId;
            private int newGroup;
    
            public ImageIdValueCallback(String imageId, String comId, int newGroup) {
                this.imageId = imageId;
                this.comId = comId;
                this.newGroup = newGroup;
            }
    
            @Override
            public String execute() {
                return dealWith(comId, newGroup, imageId);   // dealWith 是 redisLock.call 里面的 lambda 表达式里的代码块。
            }
        }
    

    这样,是不是清晰很多了 ?


  • 相关阅读:
    VS2005使用AjaxPro.2
    一步步教你实现富文本编辑器(第三部分)
    Ajax实现在textbox中输入内容,动态从数据库中模糊查询显示到下拉框中
    一步步教你实现跨游览器的JS日历
    2009年中国10大网络公司业绩比较
    Beautiful smile and love
    NGINX 配置404错误页面转向
    wget使用范例
    mcrypt以及mhash扩展的安装!
    linux下常用压缩格式的压缩与解压方法
  • 原文地址:https://www.cnblogs.com/lovesqcc/p/14639385.html
Copyright © 2020-2023  润新知